comctl32/listview: Free ID array when removing all items.
[wine] / dlls / mshtml / tests / dom.c
1 /*
2  * Copyright 2007-2008 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 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "mshtmcid.h"
31 #include "mshtmhst.h"
32 #include "docobj.h"
33 #include "dispex.h"
34 #include "mshtml_test.h"
35
36 static const char doc_blank[] = "<html></html>";
37 static const char doc_str1[] = "<html><body>test</body></html>";
38 static const char range_test_str[] =
39     "<html><body>test \na<font size=\"2\">bc\t123<br /> it's\r\n  \t</font>text<br /></body></html>";
40 static const char range_test2_str[] =
41     "<html><body>abc<hr />123<br /><hr />def</body></html>";
42 static const char elem_test_str[] =
43     "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
44     "<body onload=\"Testing()\">text test<!-- a comment -->"
45     "<a id=\"a\" href=\"http://test\" name=\"x\">link</a>"
46     "<input id=\"in\" class=\"testclass\" tabIndex=\"2\" title=\"test title\" />"
47     "<select id=\"s\"><option id=\"x\" value=\"val1\">opt1</option><option id=\"y\">opt2</option></select>"
48     "<textarea id=\"X\">text text</textarea>"
49     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td>td1 text</td><td>td2 text</td></tr></tbody></table>"
50     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
51     "<test />"
52     "<img id=\"imgid\"/>"
53     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
54     "</body></html>";
55 static const char indent_test_str[] =
56     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
57 static const char cond_comment_str[] =
58     "<html><head><title>test</title></head><body>"
59     "<!--[if gte IE 4]> <br> <![endif]-->"
60     "</body></html>";
61
62 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
63 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
64 static WCHAR wordW[] = {'w','o','r','d',0};
65
66 typedef enum {
67     ET_NONE,
68     ET_HTML,
69     ET_HEAD,
70     ET_TITLE,
71     ET_BODY,
72     ET_A,
73     ET_INPUT,
74     ET_SELECT,
75     ET_TEXTAREA,
76     ET_OPTION,
77     ET_STYLE,
78     ET_BLOCKQUOTE,
79     ET_P,
80     ET_BR,
81     ET_TABLE,
82     ET_TBODY,
83     ET_SCRIPT,
84     ET_TEST,
85     ET_TESTG,
86     ET_COMMENT,
87     ET_IMG,
88     ET_TR,
89     ET_TD,
90     ET_IFRAME
91 } elem_type_t;
92
93 static const IID * const none_iids[] = {
94     &IID_IUnknown,
95     NULL
96 };
97
98 static const IID * const doc_node_iids[] = {
99     &IID_IHTMLDOMNode,
100     &IID_IHTMLDOMNode2,
101     &IID_IHTMLDocument,
102     &IID_IHTMLDocument2,
103     &IID_IHTMLDocument3,
104     &IID_IHTMLDocument4,
105     &IID_IHTMLDocument5,
106     &IID_IDispatchEx,
107     &IID_IConnectionPointContainer,
108     &IID_IInternetHostSecurityManager,
109     NULL
110 };
111
112 static const IID * const doc_obj_iids[] = {
113     &IID_IHTMLDocument,
114     &IID_IHTMLDocument2,
115     &IID_IHTMLDocument3,
116     &IID_IHTMLDocument4,
117     &IID_IHTMLDocument5,
118     &IID_IDispatchEx,
119     &IID_IConnectionPointContainer,
120     &IID_ICustomDoc,
121     NULL
122 };
123
124 static const IID * const elem_iids[] = {
125     &IID_IHTMLDOMNode,
126     &IID_IHTMLDOMNode2,
127     &IID_IHTMLElement,
128     &IID_IHTMLElement2,
129     &IID_IHTMLElement3,
130     &IID_IDispatchEx,
131     &IID_IConnectionPointContainer,
132     NULL
133 };
134
135 static const IID * const body_iids[] = {
136     &IID_IHTMLDOMNode,
137     &IID_IHTMLDOMNode2,
138     &IID_IHTMLElement,
139     &IID_IHTMLElement2,
140     &IID_IHTMLElement3,
141     &IID_IHTMLTextContainer,
142     &IID_IHTMLBodyElement,
143     &IID_IDispatchEx,
144     &IID_IConnectionPointContainer,
145     NULL
146 };
147
148 static const IID * const anchor_iids[] = {
149     &IID_IHTMLDOMNode,
150     &IID_IHTMLDOMNode2,
151     &IID_IHTMLElement,
152     &IID_IHTMLElement2,
153     &IID_IHTMLElement3,
154     &IID_IHTMLAnchorElement,
155     &IID_IDispatchEx,
156     &IID_IConnectionPointContainer,
157     NULL
158 };
159
160 static const IID * const input_iids[] = {
161     &IID_IHTMLDOMNode,
162     &IID_IHTMLDOMNode2,
163     &IID_IHTMLElement,
164     &IID_IHTMLElement2,
165     &IID_IHTMLElement3,
166     &IID_IHTMLInputElement,
167     &IID_IHTMLInputTextElement,
168     &IID_IDispatchEx,
169     &IID_IConnectionPointContainer,
170     NULL
171 };
172
173 static const IID * const select_iids[] = {
174     &IID_IHTMLDOMNode,
175     &IID_IHTMLDOMNode2,
176     &IID_IHTMLElement,
177     &IID_IHTMLElement2,
178     &IID_IHTMLElement3,
179     &IID_IHTMLSelectElement,
180     &IID_IDispatchEx,
181     &IID_IConnectionPointContainer,
182     NULL
183 };
184
185 static const IID * const textarea_iids[] = {
186     &IID_IHTMLDOMNode,
187     &IID_IHTMLDOMNode2,
188     &IID_IHTMLElement,
189     &IID_IHTMLElement2,
190     &IID_IHTMLElement3,
191     &IID_IHTMLTextAreaElement,
192     &IID_IDispatchEx,
193     &IID_IConnectionPointContainer,
194     NULL
195 };
196
197 static const IID * const option_iids[] = {
198     &IID_IHTMLDOMNode,
199     &IID_IHTMLDOMNode2,
200     &IID_IHTMLElement,
201     &IID_IHTMLElement2,
202     &IID_IHTMLElement3,
203     &IID_IHTMLOptionElement,
204     &IID_IDispatchEx,
205     &IID_IConnectionPointContainer,
206     NULL
207 };
208
209 static const IID * const table_iids[] = {
210     &IID_IHTMLDOMNode,
211     &IID_IHTMLDOMNode2,
212     &IID_IHTMLElement,
213     &IID_IHTMLElement2,
214     &IID_IHTMLElement3,
215     &IID_IHTMLTable,
216     &IID_IDispatchEx,
217     &IID_IConnectionPointContainer,
218     NULL
219 };
220
221 static const IID * const script_iids[] = {
222     &IID_IHTMLDOMNode,
223     &IID_IHTMLDOMNode2,
224     &IID_IHTMLElement,
225     &IID_IHTMLElement2,
226     &IID_IHTMLElement3,
227     &IID_IHTMLScriptElement,
228     &IID_IDispatchEx,
229     &IID_IConnectionPointContainer,
230     NULL
231 };
232
233 static const IID * const text_iids[] = {
234     &IID_IHTMLDOMNode,
235     &IID_IHTMLDOMNode2,
236     &IID_IHTMLDOMTextNode,
237     NULL
238 };
239
240 static const IID * const location_iids[] = {
241     &IID_IDispatch,
242     &IID_IHTMLLocation,
243     NULL
244 };
245
246 static const IID * const window_iids[] = {
247     &IID_IDispatch,
248     &IID_IHTMLWindow2,
249     &IID_IHTMLWindow3,
250     &IID_IDispatchEx,
251     NULL
252 };
253
254 static const IID * const comment_iids[] = {
255     &IID_IHTMLDOMNode,
256     &IID_IHTMLDOMNode2,
257     &IID_IHTMLElement,
258     &IID_IHTMLElement2,
259     &IID_IHTMLElement3,
260     &IID_IHTMLCommentElement,
261     &IID_IDispatchEx,
262     &IID_IConnectionPointContainer,
263     NULL
264 };
265
266 static const IID * const img_iids[] = {
267     &IID_IHTMLDOMNode,
268     &IID_IHTMLDOMNode2,
269     &IID_IHTMLElement,
270     &IID_IHTMLElement2,
271     &IID_IHTMLElement3,
272     &IID_IDispatchEx,
273     &IID_IHTMLImgElement,
274     &IID_IConnectionPointContainer,
275     NULL
276 };
277
278 static const IID * const tr_iids[] = {
279     &IID_IHTMLDOMNode,
280     &IID_IHTMLDOMNode2,
281     &IID_IHTMLElement,
282     &IID_IHTMLElement2,
283     &IID_IHTMLElement3,
284     &IID_IDispatchEx,
285     &IID_IHTMLTableRow,
286     &IID_IConnectionPointContainer,
287     NULL
288 };
289
290 static const IID * const td_iids[] = {
291     &IID_IHTMLDOMNode,
292     &IID_IHTMLDOMNode2,
293     &IID_IHTMLElement,
294     &IID_IHTMLElement2,
295     &IID_IHTMLElement3,
296     &IID_IDispatchEx,
297     &IID_IConnectionPointContainer,
298     NULL
299 };
300
301 static const IID * const iframe_iids[] = {
302     &IID_IHTMLDOMNode,
303     &IID_IHTMLDOMNode2,
304     &IID_IHTMLElement,
305     &IID_IHTMLElement2,
306     &IID_IHTMLElement3,
307     &IID_IHTMLFrameBase,
308     &IID_IHTMLFrameBase2,
309     &IID_IDispatchEx,
310     &IID_IConnectionPointContainer,
311     NULL
312 };
313
314 static const IID * const generic_iids[] = {
315     &IID_IHTMLDOMNode,
316     &IID_IHTMLDOMNode2,
317     &IID_IHTMLElement,
318     &IID_IHTMLElement2,
319     &IID_IHTMLElement3,
320     &IID_IHTMLGenericElement,
321     &IID_IDispatchEx,
322     &IID_IConnectionPointContainer,
323     NULL
324 };
325
326 static const IID * const style_iids[] = {
327     &IID_IUnknown,
328     &IID_IDispatch,
329     &IID_IDispatchEx,
330     &IID_IHTMLStyle,
331     &IID_IHTMLStyle2,
332     &IID_IHTMLStyle3,
333     &IID_IHTMLStyle4,
334     NULL
335 };
336
337 static const IID * const cstyle_iids[] = {
338     &IID_IUnknown,
339     &IID_IDispatch,
340     &IID_IDispatchEx,
341     &IID_IHTMLCurrentStyle,
342     NULL
343 };
344
345 static const IID * const img_factory_iids[] = {
346     &IID_IUnknown,
347     &IID_IDispatch,
348     &IID_IDispatchEx,
349     &IID_IHTMLImageElementFactory,
350     NULL
351 };
352
353 typedef struct {
354     const char *tag;
355     REFIID *iids;
356     const IID *dispiid;
357 } elem_type_info_t;
358
359 static const elem_type_info_t elem_type_infos[] = {
360     {"",          none_iids,        NULL},
361     {"HTML",      elem_iids,        NULL},
362     {"HEAD",      elem_iids,        NULL},
363     {"TITLE",     elem_iids,        NULL},
364     {"BODY",      body_iids,        &DIID_DispHTMLBody},
365     {"A",         anchor_iids,      &DIID_DispHTMLAnchorElement},
366     {"INPUT",     input_iids,       &DIID_DispHTMLInputElement},
367     {"SELECT",    select_iids,      &DIID_DispHTMLSelectElement},
368     {"TEXTAREA",  textarea_iids,    NULL},
369     {"OPTION",    option_iids,      &DIID_DispHTMLOptionElement},
370     {"STYLE",     elem_iids,        NULL},
371     {"BLOCKQUOTE",elem_iids,        NULL},
372     {"P",         elem_iids,        NULL},
373     {"BR",        elem_iids,        NULL},
374     {"TABLE",     table_iids,       &DIID_DispHTMLTable},
375     {"TBODY",     elem_iids,        NULL},
376     {"SCRIPT",    script_iids,      NULL},
377     {"TEST",      elem_iids,        &DIID_DispHTMLUnknownElement},
378     {"TEST",      generic_iids,     &DIID_DispHTMLGenericElement},
379     {"!",         comment_iids,     &DIID_DispHTMLCommentElement},
380     {"IMG",       img_iids,         &DIID_DispHTMLImg},
381     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
382     {"TD",        td_iids,          NULL},
383     {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame}
384 };
385
386 static const char *dbgstr_guid(REFIID riid)
387 {
388     static char buf[50];
389
390     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
391             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
392             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
393             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
394
395     return buf;
396 }
397
398 static int strcmp_wa(LPCWSTR strw, const char *stra)
399 {
400     CHAR buf[512];
401     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
402     return lstrcmpA(stra, buf);
403 }
404
405 static BSTR a2bstr(const char *str)
406 {
407     BSTR ret;
408     int len;
409
410     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
411     ret = SysAllocStringLen(NULL, len);
412     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
413
414     return ret;
415 }
416
417 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
418 {
419     IUnknown *unk1, *unk2;
420
421     if(iface1 == iface2)
422         return TRUE;
423
424     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
425     IUnknown_Release(unk1);
426     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
427     IUnknown_Release(unk2);
428
429     return unk1 == unk2;
430 }
431
432 static IHTMLDocument2 *create_document(void)
433 {
434     IHTMLDocument2 *doc;
435     IHTMLDocument5 *doc5;
436     HRESULT hres;
437
438     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
439             &IID_IHTMLDocument2, (void**)&doc);
440     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
441
442     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
443     if(FAILED(hres)) {
444         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
445         IHTMLDocument2_Release(doc);
446         return NULL;
447     }
448
449     IHTMLDocument5_Release(doc5);
450     return doc;
451 }
452
453 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
454 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
455 {
456     const IID * const *piid;
457     IUnknown *unk;
458     HRESULT hres;
459
460      for(piid = iids; *piid; piid++) {
461         hres = IDispatch_QueryInterface(iface, *piid, (void**)&unk);
462         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", dbgstr_guid(*piid), hres);
463         if(SUCCEEDED(hres))
464             IUnknown_Release(unk);
465     }
466 }
467
468 #define test_get_dispid(u,id) _test_disp(__LINE__,u,id)
469 static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
470 {
471     IDispatchEx *dispex;
472     ITypeInfo *typeinfo;
473     BOOL ret = FALSE;
474     UINT ticnt;
475     HRESULT hres;
476
477     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
478     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
479     if(FAILED(hres))
480         return FALSE;
481
482     ticnt = 0xdeadbeef;
483     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
484     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
485     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
486
487     hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
488     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
489
490     if(SUCCEEDED(hres)) {
491         TYPEATTR *type_attr;
492
493         hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
494         ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
495         if(hres == S_OK) {
496             *iid = type_attr->guid;
497             ret = TRUE;
498         }
499
500         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
501         ITypeInfo_Release(typeinfo);
502     }
503
504     IDispatchEx_Release(dispex);
505     return ret;
506 }
507
508 #define test_disp_value(u) _test_disp_value(__LINE__,u,v)
509 static void _test_disp_value(unsigned line, IUnknown *unk, const char *val)
510 {
511     DISPPARAMS dp  = {NULL,NULL,0,0};
512     IDispatchEx *dispex;
513     EXCEPINFO ei;
514     VARIANT var;
515     HRESULT hres;
516
517     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
518     ok_(__FILE__,line)(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
519     if(FAILED(hres))
520         return;
521
522     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
523     IDispatchEx_Release(dispex);
524     ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres);
525
526     ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var));
527     ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val);
528     VariantClear(&var);
529 }
530
531 #define test_disp(u,id,v) _test_disp(__LINE__,u,id,v)
532 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val)
533 {
534     IID iid;
535
536     if(_test_get_dispid(line, unk, &iid))
537         ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", dbgstr_guid(&iid));
538
539     if(val)
540         _test_disp_value(line, unk, val);
541 }
542
543 #define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v)
544 static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val)
545 {
546     IID iid;
547
548     if(_test_get_dispid(line, unk, &iid))
549         ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)),
550                 "unexpected guid %s\n", dbgstr_guid(&iid));
551
552     if(val)
553         _test_disp_value(line, unk, val);
554 }
555
556 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
557 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
558 {
559     IHTMLElement *elem;
560     HRESULT hres;
561
562     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
563     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres);
564     return elem;
565 }
566
567 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
568 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
569 {
570     IHTMLElement2 *elem;
571     HRESULT hres;
572
573     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem);
574     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres);
575     return elem;
576 }
577
578 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
579 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
580 {
581     IHTMLElement3 *elem;
582     HRESULT hres;
583
584     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem);
585     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres);
586     return elem;
587 }
588
589 #define get_node_iface(u) _get_node_iface(__LINE__,u)
590 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
591 {
592     IHTMLDOMNode *node;
593     HRESULT hres;
594
595     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node);
596     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres);
597     return node;
598 }
599
600 #define get_node2_iface(u) _get_node2_iface(__LINE__,u)
601 static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk)
602 {
603     IHTMLDOMNode2 *node;
604     HRESULT hres;
605
606     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node);
607     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres);
608     return node;
609 }
610
611 #define get_img_iface(u) _get_img_iface(__LINE__,u)
612 static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk)
613 {
614     IHTMLImgElement *img;
615     HRESULT hres;
616
617     hres = IUnknown_QueryInterface(unk, &IID_IHTMLImgElement, (void**)&img);
618     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLImgElement: %08x\n", hres);
619     return img;
620 }
621
622 #define get_anchor_iface(u) _get_anchor_iface(__LINE__,u)
623 static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
624 {
625     IHTMLAnchorElement *anchor;
626     HRESULT hres;
627
628     hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor);
629     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres);
630     return anchor;
631 }
632
633 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
634 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
635 {
636     IHTMLDOMNode *node = _get_node_iface(line, unk);
637     BSTR name;
638     HRESULT hres;
639
640     hres = IHTMLDOMNode_get_nodeName(node, &name);
641     IHTMLDOMNode_Release(node);
642     ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres);
643     ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname);
644
645     SysFreeString(name);
646 }
647
648 #define get_owner_doc(u) _get_owner_doc(__LINE__,u)
649 static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
650 {
651     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
652     IDispatch *disp = (void*)0xdeadbeef;
653     IHTMLDocument2 *doc;
654     HRESULT hres;
655
656     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
657     IHTMLDOMNode2_Release(node);
658     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
659     ok_(__FILE__,line)(disp != NULL, "disp = NULL\n");
660
661     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
662     IDispatch_Release(disp);
663     ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
664
665     return doc;
666 }
667
668 #define get_doc_window(d) _get_doc_window(__LINE__,d)
669 static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
670 {
671     IHTMLWindow2 *window;
672     HRESULT hres;
673
674     window = NULL;
675     hres = IHTMLDocument2_get_parentWindow(doc, &window);
676     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
677     ok_(__FILE__,line)(window != NULL, "window == NULL\n");
678
679     return window;
680 }
681
682 #define clone_node(n,d) _clone_node(__LINE__,n,d)
683 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
684 {
685     IHTMLDOMNode *node = _get_node_iface(line, unk);
686     IHTMLDOMNode *ret = NULL;
687     HRESULT hres;
688
689     hres = IHTMLDOMNode_cloneNode(node, deep, &ret);
690     IHTMLDOMNode_Release(node);
691     ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres);
692     ok_(__FILE__,line)(ret != NULL, "ret == NULL\n");
693
694     return ret;
695
696 }
697
698 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
699 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
700 {
701     IHTMLElement *elem = _get_elem_iface(line, unk);
702     BSTR tag;
703     HRESULT hres;
704
705     hres = IHTMLElement_get_tagName(elem, &tag);
706     IHTMLElement_Release(elem);
707     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
708     ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
709
710     SysFreeString(tag);
711 }
712
713 #define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t)
714 static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type)
715 {
716     _test_elem_tag(line, unk, elem_type_infos[type].tag);
717     _test_ifaces(line, unk, elem_type_infos[type].iids);
718
719     if(elem_type_infos[type].dispiid && type != ET_A)
720         _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]");
721 }
722
723 #define get_node_type(n) _get_node_type(__LINE__,n)
724 static LONG _get_node_type(unsigned line, IUnknown *unk)
725 {
726     IHTMLDOMNode *node = _get_node_iface(line, unk);
727     LONG type = -1;
728     HRESULT hres;
729
730     hres = IHTMLDOMNode_get_nodeType(node, &type);
731     ok(hres == S_OK, "get_nodeType failed: %08x\n", hres);
732
733     IHTMLDOMNode_Release(node);
734
735     return type;
736 }
737
738 #define get_child_nodes(u) _get_child_nodes(__LINE__,u)
739 static IHTMLDOMChildrenCollection *_get_child_nodes(unsigned line, IUnknown *unk)
740 {
741     IHTMLDOMNode *node = _get_node_iface(line, unk);
742     IHTMLDOMChildrenCollection *col = NULL;
743     IDispatch *disp;
744     HRESULT hres;
745
746     hres = IHTMLDOMNode_get_childNodes(node, &disp);
747     IHTMLDOMNode_Release(node);
748     ok_(__FILE__,line) (hres == S_OK, "get_childNodes failed: %08x\n", hres);
749     if(FAILED(hres))
750         return NULL;
751
752     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMChildrenCollection, (void**)&col);
753     IDispatch_Release(disp);
754     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMChildrenCollection: %08x\n", hres);
755
756     return col;
757 }
758
759 #define get_child_item(c,i) _get_child_item(__LINE__,c,i)
760 static IHTMLDOMNode *_get_child_item(unsigned line, IHTMLDOMChildrenCollection *col, LONG idx)
761 {
762     IHTMLDOMNode *node = NULL;
763     IDispatch *disp;
764     HRESULT hres;
765
766     hres = IHTMLDOMChildrenCollection_item(col, idx, &disp);
767     ok(hres == S_OK, "item failed: %08x\n", hres);
768
769     node = _get_node_iface(line, (IUnknown*)disp);
770     IDispatch_Release(disp);
771
772     return node;
773 }
774
775 #define test_elem_attr(e,n,v) _test_elem_attr(__LINE__,e,n,v)
776 static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, const char *exval)
777 {
778     VARIANT value;
779     BSTR tmp;
780     HRESULT hres;
781
782     VariantInit(&value);
783
784     tmp = a2bstr(name);
785     hres = IHTMLElement_getAttribute(elem, tmp, 0, &value);
786     SysFreeString(tmp);
787     ok_(__FILE__,line) (hres == S_OK, "getAttribute failed: %08x\n", hres);
788
789     if(exval) {
790         ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value));
791         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value)));
792     }else {
793         ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value));
794     }
795
796     VariantClear(&value);
797 }
798
799 #define test_elem_offset(u) _test_elem_offset(__LINE__,u)
800 static void _test_elem_offset(unsigned line, IUnknown *unk)
801 {
802     IHTMLElement *elem = _get_elem_iface(line, unk);
803     LONG l;
804     HRESULT hres;
805
806     hres = IHTMLElement_get_offsetTop(elem, &l);
807     ok_(__FILE__,line) (hres == S_OK, "get_offsetTop failed: %08x\n", hres);
808
809     hres = IHTMLElement_get_offsetHeight(elem, &l);
810     ok_(__FILE__,line) (hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
811
812     hres = IHTMLElement_get_offsetWidth(elem, &l);
813     ok_(__FILE__,line) (hres == S_OK, "get_offsetWidth failed: %08x\n", hres);
814
815     IHTMLElement_Release(elem);
816 }
817
818 #define get_doc_node(d) _get_doc_node(__LINE__,d)
819 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
820 {
821     IHTMLWindow2 *window;
822     IHTMLDocument2 *ret;
823     HRESULT hres;
824
825     hres = IHTMLDocument2_get_parentWindow(doc, &window);
826     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
827
828     hres = IHTMLWindow2_get_document(window, &ret);
829     ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres);
830     ok_(__FILE__,line)(ret != NULL, "document = NULL\n");
831
832     return ret;
833 }
834
835 #define test_window_name(d,e) _test_window_name(__LINE__,d,e)
836 static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
837 {
838     BSTR name;
839     HRESULT hres;
840
841     hres = IHTMLWindow2_get_name(window, &name);
842     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
843     if(exname)
844         ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
845     else
846         ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
847 }
848
849 #define set_window_name(w,n) _set_window_name(__LINE__,w,n)
850 static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
851 {
852     BSTR str;
853     HRESULT hres;
854
855     str = a2bstr(name);
856     hres = IHTMLWindow2_put_name(window, str);
857     SysFreeString(str);
858     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
859
860     _test_window_name(line, window, name);
861 }
862
863 #define test_window_length(w,l) _test_window_length(__LINE__,w,l)
864 static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
865 {
866     LONG length = -1;
867     HRESULT hres;
868
869     hres = IHTMLWindow2_get_length(window, &length);
870     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
871     ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
872 }
873
874 static void test_get_set_attr(IHTMLDocument2 *doc)
875 {
876     IHTMLElement *elem;
877     IHTMLDocument3 *doc3;
878     HRESULT hres;
879     BSTR bstr;
880     VARIANT val;
881
882     /* grab an element to test with */
883     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
884     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
885
886     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
887     IHTMLDocument3_Release(doc3);
888     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
889
890     /* get a non-present attribute */
891     bstr = a2bstr("notAnAttribute");
892     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
893     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
894     ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val));
895     VariantClear(&val);
896     SysFreeString(bstr);
897
898     /* get a present attribute */
899     bstr = a2bstr("scrollHeight");
900     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
901     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
902     ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val));
903     VariantClear(&val);
904     SysFreeString(bstr);
905
906     /* create a new BSTR attribute */
907     bstr = a2bstr("newAttribute");
908
909     V_VT(&val) = VT_BSTR;
910     V_BSTR(&val) = a2bstr("the value");
911     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
912     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
913     VariantClear(&val);
914
915     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
916     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
917     ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val));
918     ok(strcmp_wa(V_BSTR(&val), "the value") == 0, "variant value should have been L\"the value\", was %s\n", wine_dbgstr_w(V_BSTR(&val)));
919     VariantClear(&val);
920
921     /* overwrite the attribute with a BOOL */
922     V_VT(&val) = VT_BOOL;
923     V_BOOL(&val) = VARIANT_TRUE;
924     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
925     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
926     VariantClear(&val);
927
928     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
929     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
930     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
931     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
932     VariantClear(&val);
933
934     SysFreeString(bstr);
935
936     /* case-insensitive */
937     bstr = a2bstr("newattribute");
938     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
939     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
940     todo_wine ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
941     todo_wine ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
942     VariantClear(&val);
943     SysFreeString(bstr);
944
945     IHTMLElement_Release(elem);
946 }
947
948 #define get_doc_elem(d) _get_doc_elem(__LINE__,d)
949 static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc)
950 {
951     IHTMLElement *elem;
952     IHTMLDocument3 *doc3;
953     HRESULT hres;
954
955     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
956     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
957     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
958     ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres);
959     IHTMLDocument3_Release(doc3);
960
961     return elem;
962 }
963
964 #define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h)
965 static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref)
966 {
967     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
968     BSTR str;
969     HRESULT hres;
970
971     hres = IHTMLAnchorElement_get_href(anchor, &str);
972     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
973     ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref);
974     SysFreeString(str);
975
976     _test_disp_value(line, unk, exhref);
977 }
978
979 #define test_option_text(o,t) _test_option_text(__LINE__,o,t)
980 static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text)
981 {
982     BSTR bstr;
983     HRESULT hres;
984
985     hres = IHTMLOptionElement_get_text(option, &bstr);
986     ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres);
987     ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr));
988     SysFreeString(bstr);
989 }
990
991 #define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t)
992 static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text)
993 {
994     BSTR bstr;
995     HRESULT hres;
996
997     bstr = a2bstr(text);
998     hres = IHTMLOptionElement_put_text(option, bstr);
999     SysFreeString(bstr);
1000     ok(hres == S_OK, "put_text failed: %08x\n", hres);
1001
1002     _test_option_text(line, option, text);
1003 }
1004
1005 #define test_option_value(o,t) _test_option_value(__LINE__,o,t)
1006 static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value)
1007 {
1008     BSTR bstr;
1009     HRESULT hres;
1010
1011     hres = IHTMLOptionElement_get_value(option, &bstr);
1012     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1013     ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr));
1014     SysFreeString(bstr);
1015 }
1016
1017 #define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t)
1018 static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value)
1019 {
1020     BSTR bstr;
1021     HRESULT hres;
1022
1023     bstr = a2bstr(value);
1024     hres = IHTMLOptionElement_put_value(option, bstr);
1025     SysFreeString(bstr);
1026     ok(hres == S_OK, "put_value failed: %08x\n", hres);
1027
1028     _test_option_value(line, option, value);
1029 }
1030
1031 #define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v)
1032 static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc,
1033         const char *txt, const char *val)
1034 {
1035     IHTMLOptionElementFactory *factory;
1036     IHTMLOptionElement *option;
1037     IHTMLWindow2 *window;
1038     VARIANT text, value, empty;
1039     HRESULT hres;
1040
1041     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1042     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1043
1044     hres = IHTMLWindow2_get_Option(window, &factory);
1045     IHTMLWindow2_Release(window);
1046     ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres);
1047
1048     V_VT(&text) = VT_BSTR;
1049     V_BSTR(&text) = a2bstr(txt);
1050     V_VT(&value) = VT_BSTR;
1051     V_BSTR(&value) = a2bstr(val);
1052     V_VT(&empty) = VT_EMPTY;
1053
1054     hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option);
1055     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1056
1057     IHTMLOptionElementFactory_Release(factory);
1058     VariantClear(&text);
1059     VariantClear(&value);
1060
1061     _test_option_text(line, option, txt);
1062     _test_option_value(line, option, val);
1063
1064     return option;
1065 }
1066
1067 #define test_img_width(o,w) _test_img_width(__LINE__,o,w)
1068 static void _test_img_width(unsigned line, IHTMLImgElement *img, const long exp)
1069 {
1070     LONG found = -1;
1071     HRESULT hres;
1072
1073     hres = IHTMLImgElement_get_width(img, &found);
1074     todo_wine ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
1075     todo_wine ok_(__FILE__,line) (found == exp, "width=%d\n", found);
1076 }
1077
1078 #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
1079 static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const long width)
1080 {
1081     HRESULT hres;
1082
1083     hres = IHTMLImgElement_put_width(img, width);
1084     todo_wine ok(hres == S_OK, "put_width failed: %08x\n", hres);
1085
1086     _test_img_width(line, img, width);
1087 }
1088
1089 #define test_img_height(o,h) _test_img_height(__LINE__,o,h)
1090 static void _test_img_height(unsigned line, IHTMLImgElement *img, const long exp)
1091 {
1092     LONG found = -1;
1093     HRESULT hres;
1094
1095     hres = IHTMLImgElement_get_height(img, &found);
1096     todo_wine ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
1097     todo_wine ok_(__FILE__,line) (found == exp, "height=%d\n", found);
1098 }
1099
1100 #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
1101 static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const long height)
1102 {
1103     HRESULT hres;
1104
1105     hres = IHTMLImgElement_put_height(img, height);
1106     todo_wine ok(hres == S_OK, "put_height failed: %08x\n", hres);
1107
1108     _test_img_height(line, img, height);
1109 }
1110
1111 #define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
1112 static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
1113         LONG wdth, LONG hght)
1114 {
1115     IHTMLImageElementFactory *factory;
1116     IHTMLImgElement *img;
1117     IHTMLWindow2 *window;
1118     VARIANT width, height;
1119     char buf[16];
1120     HRESULT hres;
1121
1122     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1123     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1124
1125     hres = IHTMLWindow2_get_Image(window, &factory);
1126     IHTMLWindow2_Release(window);
1127     ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
1128
1129     test_ifaces((IUnknown*)factory, img_factory_iids);
1130     test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
1131
1132     if(wdth >= 0){
1133         snprintf(buf, 16, "%d", wdth);
1134         V_VT(&width) = VT_BSTR;
1135         V_BSTR(&width) = a2bstr(buf);
1136     }else{
1137         V_VT(&width) = VT_EMPTY;
1138         wdth = 0;
1139     }
1140
1141     if(hght >= 0){
1142         snprintf(buf, 16, "%d", hght);
1143         V_VT(&height) = VT_BSTR;
1144         V_BSTR(&height) = a2bstr(buf);
1145     }else{
1146         V_VT(&height) = VT_EMPTY;
1147         hght = 0;
1148     }
1149
1150     hres = IHTMLImageElementFactory_create(factory, width, height, &img);
1151     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1152
1153     IHTMLImageElementFactory_Release(factory);
1154     VariantClear(&width);
1155     VariantClear(&height);
1156
1157     if(SUCCEEDED(hres)) {
1158         _test_img_width(line, img, wdth);
1159         _test_img_height(line, img, hght);
1160         return img;
1161     }
1162
1163     return NULL;
1164 }
1165
1166 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
1167 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
1168 {
1169     LONG len = 0xdeadbeef;
1170     HRESULT hres;
1171
1172     hres = IHTMLSelectElement_get_length(select, &len);
1173     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1174     ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length);
1175 }
1176
1177 #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i)
1178 static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1179 {
1180     LONG idx = 0xdeadbeef;
1181     HRESULT hres;
1182
1183     hres = IHTMLSelectElement_get_selectedIndex(select, &idx);
1184     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1185     ok_(__FILE__,line) (idx == index, "idx=%d, expected %d\n", idx, index);
1186 }
1187
1188 #define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i)
1189 static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1190 {
1191     HRESULT hres;
1192
1193     hres = IHTMLSelectElement_put_selectedIndex(select, index);
1194     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1195     _test_select_selidx(line, select, index);
1196 }
1197
1198 #define test_select_value(s,v) _test_select_value(__LINE__,s,v)
1199 static void _test_select_value(unsigned line, IHTMLSelectElement *select, const char *exval)
1200 {
1201     BSTR val;
1202     HRESULT hres;
1203
1204     hres = IHTMLSelectElement_get_value(select, &val);
1205     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1206     if(exval)
1207         ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val));
1208     else
1209         ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val));
1210 }
1211
1212 #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v)
1213 static void _test_select_set_value(unsigned line, IHTMLSelectElement *select, const char *val)
1214 {
1215     BSTR bstr;
1216     HRESULT hres;
1217
1218     bstr = a2bstr(val);
1219     hres = IHTMLSelectElement_put_value(select, bstr);
1220     SysFreeString(bstr);
1221     ok_(__FILE__,line) (hres == S_OK, "put_value failed: %08x\n", hres);
1222 }
1223
1224 #define test_select_type(s,t) _test_select_type(__LINE__,s,t)
1225 static void _test_select_type(unsigned line, IHTMLSelectElement *select, const char *extype)
1226 {
1227     BSTR type;
1228     HRESULT hres;
1229
1230     hres = IHTMLSelectElement_get_type(select, &type);
1231     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
1232     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
1233 }
1234
1235 #define test_range_text(r,t) _test_range_text(__LINE__,r,t)
1236 static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext)
1237 {
1238     BSTR text;
1239     HRESULT hres;
1240
1241     hres = IHTMLTxtRange_get_text(range, &text);
1242     ok_(__FILE__, line) (hres == S_OK, "get_text failed: %08x\n", hres);
1243
1244     if(extext) {
1245         ok_(__FILE__, line) (text != NULL, "text == NULL\n");
1246         ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext);
1247     }else {
1248         ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text));
1249     }
1250
1251     SysFreeString(text);
1252
1253 }
1254
1255 #define test_range_collapse(r,b) _test_range_collapse(__LINE__,r,b)
1256 static void _test_range_collapse(unsigned line, IHTMLTxtRange *range, BOOL b)
1257 {
1258     HRESULT hres;
1259
1260     hres = IHTMLTxtRange_collapse(range, b);
1261     ok_(__FILE__, line) (hres == S_OK, "collapse failed: %08x\n", hres);
1262     _test_range_text(line, range, NULL);
1263 }
1264
1265 #define test_range_expand(r,u,b,t) _test_range_expand(__LINE__,r,u,b,t)
1266 static void _test_range_expand(unsigned line, IHTMLTxtRange *range, LPWSTR unit,
1267         VARIANT_BOOL exb, const char *extext)
1268 {
1269     VARIANT_BOOL b = 0xe0e0;
1270     HRESULT hres;
1271
1272     hres = IHTMLTxtRange_expand(range, unit, &b);
1273     ok_(__FILE__,line) (hres == S_OK, "expand failed: %08x\n", hres);
1274     ok_(__FILE__,line) (b == exb, "b=%x, expected %x\n", b, exb);
1275     _test_range_text(line, range, extext);
1276 }
1277
1278 #define test_range_move(r,u,c,e) _test_range_move(__LINE__,r,u,c,e)
1279 static void _test_range_move(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1280 {
1281     LONG c = 0xdeadbeef;
1282     HRESULT hres;
1283
1284     hres = IHTMLTxtRange_move(range, unit, cnt, &c);
1285     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1286     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1287     _test_range_text(line, range, NULL);
1288 }
1289
1290 #define test_range_movestart(r,u,c,e) _test_range_movestart(__LINE__,r,u,c,e)
1291 static void _test_range_movestart(unsigned line, IHTMLTxtRange *range,
1292         LPWSTR unit, LONG cnt, LONG excnt)
1293 {
1294     LONG c = 0xdeadbeef;
1295     HRESULT hres;
1296
1297     hres = IHTMLTxtRange_moveStart(range, unit, cnt, &c);
1298     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1299     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1300 }
1301
1302 #define test_range_moveend(r,u,c,e) _test_range_moveend(__LINE__,r,u,c,e)
1303 static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1304 {
1305     LONG c = 0xdeadbeef;
1306     HRESULT hres;
1307
1308     hres = IHTMLTxtRange_moveEnd(range, unit, cnt, &c);
1309     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1310     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1311 }
1312
1313 #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
1314 static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
1315 {
1316     HRESULT hres;
1317     BSTR bstr = a2bstr(text);
1318
1319     hres = IHTMLTxtRange_put_text(range, bstr);
1320     ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
1321     SysFreeString(bstr);
1322     _test_range_text(line, range, NULL);
1323 }
1324
1325 #define test_range_inrange(r1,r2,b) _test_range_inrange(__LINE__,r1,r2,b)
1326 static void _test_range_inrange(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1327 {
1328     VARIANT_BOOL b;
1329     HRESULT hres;
1330
1331     b = 0xe0e0;
1332     hres = IHTMLTxtRange_inRange(range1, range2, &b);
1333     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1334     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1335 }
1336
1337 #define test_range_isequal(r1,r2,b) _test_range_isequal(__LINE__,r1,r2,b)
1338 static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1339 {
1340     VARIANT_BOOL b;
1341     HRESULT hres;
1342
1343     b = 0xe0e0;
1344     hres = IHTMLTxtRange_isEqual(range1, range2, &b);
1345     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1346     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1347
1348     b = 0xe0e0;
1349     hres = IHTMLTxtRange_isEqual(range2, range1, &b);
1350     ok_(__FILE__,line) (hres == S_OK, "(2->1) isEqual failed: %08x\n", hres);
1351     ok_(__FILE__,line) (b == exb, "(2->1) b=%x, expected %x\n", b, exb);
1352
1353     if(exb) {
1354         test_range_inrange(range1, range2, VARIANT_TRUE);
1355         test_range_inrange(range2, range1, VARIANT_TRUE);
1356     }
1357 }
1358
1359 #define test_range_parent(r,t) _test_range_parent(__LINE__,r,t)
1360 static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t type)
1361 {
1362     IHTMLElement *elem;
1363     HRESULT hres;
1364
1365     hres = IHTMLTxtRange_parentElement(range, &elem);
1366     ok_(__FILE__,line) (hres == S_OK, "parentElement failed: %08x\n", hres);
1367
1368     _test_elem_type(line, (IUnknown*)elem, type);
1369
1370     IHTMLElement_Release(elem);
1371 }
1372
1373 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
1374 static void _test_elem_collection(unsigned line, IUnknown *unk,
1375         const elem_type_t *elem_types, LONG exlen)
1376 {
1377     IHTMLElementCollection *col;
1378     LONG len;
1379     DWORD i;
1380     VARIANT name, index;
1381     IDispatch *disp, *disp2;
1382     HRESULT hres;
1383
1384     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col);
1385     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres);
1386
1387     test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]");
1388
1389     hres = IHTMLElementCollection_get_length(col, &len);
1390     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1391     ok_(__FILE__,line) (len == exlen, "len=%d, expected %d\n", len, exlen);
1392
1393     if(len > exlen)
1394         len = exlen;
1395
1396     V_VT(&index) = VT_EMPTY;
1397
1398     for(i=0; i<len; i++) {
1399         V_VT(&name) = VT_I4;
1400         V_I4(&name) = i;
1401         disp = (void*)0xdeadbeef;
1402         hres = IHTMLElementCollection_item(col, name, index, &disp);
1403         ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
1404         ok_(__FILE__,line) (disp != NULL, "item returned NULL\n");
1405         if(FAILED(hres) || !disp)
1406             continue;
1407
1408         _test_elem_type(line, (IUnknown*)disp, elem_types[i]);
1409
1410         if(!i) {
1411             V_VT(&name) = VT_UINT;
1412             V_I4(&name) = 0;
1413             disp2 = (void*)0xdeadbeef;
1414             hres = IHTMLElementCollection_item(col, name, index, &disp2);
1415             ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
1416             ok_(__FILE__,line) (iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
1417             if(disp2)
1418                 IDispatch_Release(disp2);
1419         }
1420
1421         IDispatch_Release(disp);
1422     }
1423
1424     V_VT(&name) = VT_I4;
1425     V_I4(&name) = len;
1426     disp = (void*)0xdeadbeef;
1427     hres = IHTMLElementCollection_item(col, name, index, &disp);
1428     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
1429     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
1430
1431     V_VT(&name) = VT_I4;
1432     V_I4(&name) = -1;
1433     disp = (void*)0xdeadbeef;
1434     hres = IHTMLElementCollection_item(col, name, index, &disp);
1435     ok_(__FILE__,line) (hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
1436     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
1437
1438     IHTMLElementCollection_Release(col);
1439 }
1440
1441 #define test_elem_all(c,t,l) _test_elem_all(__LINE__,c,t,l)
1442 static void _test_elem_all(unsigned line, IUnknown *unk, const elem_type_t *elem_types, LONG exlen)
1443 {
1444     IHTMLElement *elem = _get_elem_iface(line, unk);
1445     IDispatch *disp;
1446     HRESULT hres;
1447
1448     hres = IHTMLElement_get_all(elem, &disp);
1449     IHTMLElement_Release(elem);
1450     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
1451
1452     _test_elem_collection(line, (IUnknown*)disp, elem_types, exlen);
1453     IDispatch_Release(disp);
1454 }
1455
1456 #define test_elem_getelembytag(u,t,l) _test_elem_getelembytag(__LINE__,u,t,l)
1457 static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t type, LONG exlen)
1458 {
1459     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1460     IHTMLElementCollection *col = NULL;
1461     elem_type_t *types = NULL;
1462     BSTR tmp;
1463     int i;
1464     HRESULT hres;
1465
1466     tmp = a2bstr(elem_type_infos[type].tag);
1467     hres = IHTMLElement2_getElementsByTagName(elem, tmp, &col);
1468     SysFreeString(tmp);
1469     IHTMLElement2_Release(elem);
1470     ok_(__FILE__,line) (hres == S_OK, "getElementByTagName failed: %08x\n", hres);
1471     ok_(__FILE__,line) (col != NULL, "col == NULL\n");
1472
1473     if(exlen) {
1474         types = HeapAlloc(GetProcessHeap(), 0, exlen*sizeof(elem_type_t));
1475         for(i=0; i<exlen; i++)
1476             types[i] = type;
1477     }
1478
1479     _test_elem_collection(line, (IUnknown*)col, types, exlen);
1480
1481     HeapFree(GetProcessHeap(), 0, types);
1482 }
1483
1484 #define test_elem_innertext(e,t) _test_elem_innertext(__LINE__,e,t)
1485 static void _test_elem_innertext(unsigned line, IHTMLElement *elem, const char *extext)
1486 {
1487     BSTR text = NULL;
1488     HRESULT hres;
1489
1490     hres = IHTMLElement_get_innerText(elem, &text);
1491     ok_(__FILE__,line) (hres == S_OK, "get_innerText failed: %08x\n", hres);
1492     ok_(__FILE__,line) (!strcmp_wa(text, extext), "get_innerText returned %s expected %s\n",
1493                         wine_dbgstr_w(text), extext);
1494     SysFreeString(text);
1495 }
1496
1497 #define test_elem_set_innertext(e,t) _test_elem_set_innertext(__LINE__,e,t)
1498 static void _test_elem_set_innertext(unsigned line, IHTMLElement *elem, const char *text)
1499 {
1500     IHTMLDOMChildrenCollection *col;
1501     BSTR str;
1502     HRESULT hres;
1503
1504     str = a2bstr(text);
1505     hres = IHTMLElement_put_innerText(elem, str);
1506     ok_(__FILE__,line) (hres == S_OK, "put_innerText failed: %08x\n", hres);
1507     SysFreeString(str);
1508
1509     _test_elem_innertext(line, elem, text);
1510
1511
1512     col = _get_child_nodes(line, (IUnknown*)elem);
1513     ok(col != NULL, "col == NULL\n");
1514     if(col) {
1515         LONG length = 0, type;
1516         IHTMLDOMNode *node;
1517
1518         hres = IHTMLDOMChildrenCollection_get_length(col, &length);
1519         ok(hres == S_OK, "get_length failed: %08x\n", hres);
1520         ok(length == 1, "length = %d\n", length);
1521
1522         node = _get_child_item(line, col, 0);
1523         ok(node != NULL, "node == NULL\n");
1524         if(node) {
1525             type = _get_node_type(line, (IUnknown*)node);
1526             ok(type == 3, "type=%d\n", type);
1527             IHTMLDOMNode_Release(node);
1528         }
1529
1530         IHTMLDOMChildrenCollection_Release(col);
1531     }
1532
1533 }
1534
1535 #define test_elem_innerhtml(e,t) _test_elem_innerhtml(__LINE__,e,t)
1536 static void _test_elem_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
1537 {
1538     IHTMLElement *elem = _get_elem_iface(line, unk);
1539     BSTR html;
1540     HRESULT hres;
1541
1542     hres = IHTMLElement_get_innerHTML(elem, &html);
1543     ok_(__FILE__,line)(hres == S_OK, "get_innerHTML failed: %08x\n", hres);
1544     if(inner_html)
1545         ok_(__FILE__,line)(!strcmp_wa(html, inner_html), "unexpected innerHTML: %s\n", wine_dbgstr_w(html));
1546     else
1547         ok_(__FILE__,line)(!html, "innerHTML = %s\n", wine_dbgstr_w(html));
1548
1549     IHTMLElement_Release(elem);
1550     SysFreeString(html);
1551 }
1552
1553 #define test_elem_set_innerhtml(e,t) _test_elem_set_innerhtml(__LINE__,e,t)
1554 static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
1555 {
1556     IHTMLElement *elem = _get_elem_iface(line, unk);
1557     BSTR html;
1558     HRESULT hres;
1559
1560     html = a2bstr(inner_html);
1561     hres = IHTMLElement_put_innerHTML(elem, html);
1562     ok_(__FILE__,line)(hres == S_OK, "put_innerHTML failed: %08x\n", hres);
1563
1564     IHTMLElement_Release(elem);
1565     SysFreeString(html);
1566 }
1567
1568 #define get_first_child(n) _get_first_child(__LINE__,n)
1569 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
1570 {
1571     IHTMLDOMNode *node = _get_node_iface(line, unk);
1572     IHTMLDOMNode *child = NULL;
1573     HRESULT hres;
1574
1575     hres = IHTMLDOMNode_get_firstChild(node, &child);
1576     IHTMLDOMNode_Release(node);
1577     ok_(__FILE__,line) (hres == S_OK, "get_firstChild failed: %08x\n", hres);
1578
1579     return child;
1580 }
1581
1582 #define test_node_has_child(u,b) _test_node_has_child(__LINE__,u,b)
1583 static void _test_node_has_child(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
1584 {
1585     IHTMLDOMNode *node = _get_node_iface(line, unk);
1586     VARIANT_BOOL b = 0xdead;
1587     HRESULT hres;
1588
1589     hres = IHTMLDOMNode_hasChildNodes(node, &b);
1590     ok_(__FILE__,line) (hres == S_OK, "hasChildNodes failed: %08x\n", hres);
1591     ok_(__FILE__,line) (b == exb, "hasChildNodes=%x, expected %x\n", b, exb);
1592
1593     IHTMLDOMNode_Release(node);
1594 }
1595
1596 #define test_node_get_parent(u) _test_node_get_parent(__LINE__,u)
1597 static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
1598 {
1599     IHTMLDOMNode *node = _get_node_iface(line, unk);
1600     IHTMLDOMNode *parent;
1601     HRESULT hres;
1602
1603     hres = IHTMLDOMNode_get_parentNode(node, &parent);
1604     IHTMLDOMNode_Release(node);
1605     ok_(__FILE__,line) (hres == S_OK, "get_parentNode failed: %08x\n", hres);
1606
1607     return parent;
1608 }
1609
1610 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
1611 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
1612 {
1613     IHTMLElement *elem = _get_elem_iface(line, unk);
1614     IHTMLElement *parent;
1615     HRESULT hres;
1616
1617     hres = IHTMLElement_get_parentElement(elem, &parent);
1618     IHTMLElement_Release(elem);
1619     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1620
1621     return parent;
1622 }
1623
1624 #define test_elem3_get_disabled(i,b) _test_elem3_get_disabled(__LINE__,i,b)
1625 static void _test_elem3_get_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
1626 {
1627     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
1628     VARIANT_BOOL disabled = 100;
1629     HRESULT hres;
1630
1631     if (!elem3) return;
1632     hres = IHTMLElement3_get_disabled(elem3, &disabled);
1633     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1634     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
1635     IHTMLElement3_Release(elem3);
1636 }
1637
1638 #define test_elem3_set_disabled(i,b) _test_elem3_set_disabled(__LINE__,i,b)
1639 static void _test_elem3_set_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL b)
1640 {
1641     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
1642     HRESULT hres;
1643
1644     if (!elem3) return;
1645     hres = IHTMLElement3_put_disabled(elem3, b);
1646     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1647
1648     IHTMLElement3_Release(elem3);
1649     _test_elem3_get_disabled(line, unk, b);
1650 }
1651
1652 #define test_select_get_disabled(i,b) _test_select_get_disabled(__LINE__,i,b)
1653 static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exb)
1654 {
1655     VARIANT_BOOL disabled = 100;
1656     HRESULT hres;
1657
1658     hres = IHTMLSelectElement_get_disabled(select, &disabled);
1659     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1660     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
1661
1662     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
1663 }
1664
1665 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
1666 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
1667 {
1668     HRESULT hres;
1669
1670     hres = IHTMLSelectElement_put_disabled(select, b);
1671     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1672
1673     _test_select_get_disabled(line, select, b);
1674 }
1675
1676 #define elem_get_scroll_height(u) _elem_get_scroll_height(__LINE__,u)
1677 static LONG _elem_get_scroll_height(unsigned line, IUnknown *unk)
1678 {
1679     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1680     IHTMLTextContainer *txtcont;
1681     LONG l = -1, l2 = -1;
1682     HRESULT hres;
1683
1684     hres = IHTMLElement2_get_scrollHeight(elem, &l);
1685     ok_(__FILE__,line) (hres == S_OK, "get_scrollHeight failed: %08x\n", hres);
1686     IHTMLElement2_Release(elem);
1687
1688     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1689     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1690
1691     hres = IHTMLTextContainer_get_scrollHeight(txtcont, &l2);
1692     IHTMLTextContainer_Release(txtcont);
1693     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollHeight failed: %d\n", l2);
1694     ok_(__FILE__,line) (l == l2, "unexpected height %d, expected %d\n", l2, l);
1695
1696     return l;
1697 }
1698
1699 #define elem_get_scroll_width(u) _elem_get_scroll_width(__LINE__,u)
1700 static LONG _elem_get_scroll_width(unsigned line, IUnknown *unk)
1701 {
1702     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1703     IHTMLTextContainer *txtcont;
1704     LONG l = -1, l2 = -1;
1705     HRESULT hres;
1706
1707     hres = IHTMLElement2_get_scrollWidth(elem, &l);
1708     ok_(__FILE__,line) (hres == S_OK, "get_scrollWidth failed: %08x\n", hres);
1709     IHTMLElement2_Release(elem);
1710
1711     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1712     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1713
1714     hres = IHTMLTextContainer_get_scrollWidth(txtcont, &l2);
1715     IHTMLTextContainer_Release(txtcont);
1716     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollWidth failed: %d\n", l2);
1717     ok_(__FILE__,line) (l == l2, "unexpected width %d, expected %d\n", l2, l);
1718
1719     return l;
1720 }
1721
1722 #define elem_get_scroll_top(u) _elem_get_scroll_top(__LINE__,u)
1723 static LONG _elem_get_scroll_top(unsigned line, IUnknown *unk)
1724 {
1725     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1726     IHTMLTextContainer *txtcont;
1727     LONG l = -1, l2 = -1;
1728     HRESULT hres;
1729
1730     hres = IHTMLElement2_get_scrollTop(elem, &l);
1731     ok_(__FILE__,line) (hres == S_OK, "get_scrollTop failed: %08x\n", hres);
1732     IHTMLElement2_Release(elem);
1733
1734     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1735     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1736
1737     hres = IHTMLTextContainer_get_scrollTop(txtcont, &l2);
1738     IHTMLTextContainer_Release(txtcont);
1739     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollTop failed: %d\n", l2);
1740     ok_(__FILE__,line) (l == l2, "unexpected top %d, expected %d\n", l2, l);
1741
1742     return l;
1743 }
1744
1745 #define elem_get_scroll_left(u) _elem_get_scroll_left(__LINE__,u)
1746 static void _elem_get_scroll_left(unsigned line, IUnknown *unk)
1747 {
1748     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1749     IHTMLTextContainer *txtcont;
1750     LONG l = -1, l2 = -1;
1751     HRESULT hres;
1752
1753     hres = IHTMLElement2_get_scrollLeft(elem, NULL);
1754     ok(hres == E_INVALIDARG, "expect E_INVALIDARG got 0x%08x\n", hres);
1755
1756     hres = IHTMLElement2_get_scrollLeft(elem, &l);
1757     ok(hres == S_OK, "get_scrollTop failed: %08x\n", hres);
1758     IHTMLElement2_Release(elem);
1759
1760     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1761     ok(hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1762
1763     hres = IHTMLTextContainer_get_scrollLeft(txtcont, &l2);
1764     IHTMLTextContainer_Release(txtcont);
1765     ok(hres == S_OK, "IHTMLTextContainer::get_scrollLeft failed: %d\n", l2);
1766     ok(l == l2, "unexpected left %d, expected %d\n", l2, l);
1767 }
1768
1769 #define test_img_src(i,s) _test_img_src(__LINE__,i,s)
1770 static void _test_img_src(unsigned line, IUnknown *unk, const char *exsrc)
1771 {
1772     IHTMLImgElement *img = _get_img_iface(line, unk);
1773     BSTR src;
1774     HRESULT hres;
1775
1776     hres = IHTMLImgElement_get_src(img, &src);
1777     IHTMLImgElement_Release(img);
1778     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
1779     ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
1780     SysFreeString(src);
1781 }
1782
1783 #define test_img_set_src(u,s) _test_img_set_src(__LINE__,u,s)
1784 static void _test_img_set_src(unsigned line, IUnknown *unk, const char *src)
1785 {
1786     IHTMLImgElement *img = _get_img_iface(line, unk);
1787     BSTR tmp;
1788     HRESULT hres;
1789
1790     tmp = a2bstr(src);
1791     hres = IHTMLImgElement_put_src(img, tmp);
1792     IHTMLImgElement_Release(img);
1793     SysFreeString(tmp);
1794     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
1795
1796     _test_img_src(line, unk, src);
1797 }
1798
1799 #define test_img_alt(u,a) _test_img_alt(__LINE__,u,a)
1800 static void _test_img_alt(unsigned line, IUnknown *unk, const char *exalt)
1801 {
1802     IHTMLImgElement *img = _get_img_iface(line, unk);
1803     BSTR alt;
1804     HRESULT hres;
1805
1806     hres = IHTMLImgElement_get_alt(img, &alt);
1807     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
1808     if(exalt)
1809         ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "inexopected alt %s\n", wine_dbgstr_w(alt));
1810     else
1811         ok_(__FILE__,line) (!alt, "alt != NULL\n");
1812     SysFreeString(alt);
1813 }
1814
1815 #define test_img_set_alt(u,a) _test_img_set_alt(__LINE__,u,a)
1816 static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
1817 {
1818     IHTMLImgElement *img = _get_img_iface(line, unk);
1819     BSTR tmp;
1820     HRESULT hres;
1821
1822     tmp = a2bstr(alt);
1823     hres = IHTMLImgElement_put_alt(img, tmp);
1824     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
1825     SysFreeString(tmp);
1826
1827     _test_img_alt(line, unk, alt);
1828 }
1829
1830 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
1831 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
1832 {
1833     VARIANT_BOOL disabled = 100;
1834     HRESULT hres;
1835
1836     hres = IHTMLInputElement_get_disabled(input, &disabled);
1837     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1838     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
1839
1840     _test_elem3_get_disabled(line, (IUnknown*)input, exb);
1841 }
1842
1843 #define test_input_set_disabled(i,b) _test_input_set_disabled(__LINE__,i,b)
1844 static void _test_input_set_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
1845 {
1846     HRESULT hres;
1847
1848     hres = IHTMLInputElement_put_disabled(input, b);
1849     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1850
1851     _test_input_get_disabled(line, input, b);
1852 }
1853
1854 #define test_input_get_defaultchecked(i,b) _test_input_get_defaultchecked(__LINE__,i,b)
1855 static void _test_input_get_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
1856 {
1857     VARIANT_BOOL checked = 100;
1858     HRESULT hres;
1859
1860     hres = IHTMLInputElement_get_defaultChecked(input, &checked);
1861     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
1862     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
1863 }
1864
1865 #define test_input_set_defaultchecked(i,b) _test_input_set_defaultchecked(__LINE__,i,b)
1866 static void _test_input_set_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
1867 {
1868     HRESULT hres;
1869
1870     hres = IHTMLInputElement_put_defaultChecked(input, b);
1871     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
1872
1873     _test_input_get_defaultchecked(line, input, b);
1874 }
1875
1876 #define test_input_get_checked(i,b) _test_input_get_checked(__LINE__,i,b)
1877 static void _test_input_get_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
1878 {
1879     VARIANT_BOOL checked = 100;
1880     HRESULT hres;
1881
1882     hres = IHTMLInputElement_get_checked(input, &checked);
1883     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
1884     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
1885 }
1886
1887 #define test_input_set_checked(i,b) _test_input_set_checked(__LINE__,i,b)
1888 static void _test_input_set_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
1889 {
1890     HRESULT hres;
1891
1892     hres = IHTMLInputElement_put_checked(input, b);
1893     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
1894
1895     _test_input_get_checked(line, input, b);
1896 }
1897
1898 #define test_input_value(o,t) _test_input_value(__LINE__,o,t)
1899 static void _test_input_value(unsigned line, IUnknown *unk, const char *exval)
1900 {
1901     IHTMLInputElement *input;
1902     BSTR bstr;
1903     HRESULT hres;
1904
1905     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
1906     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
1907     if(FAILED(hres))
1908         return;
1909
1910     hres = IHTMLInputElement_get_value(input, &bstr);
1911     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1912     if(exval)
1913         ok_(__FILE__,line) (!strcmp_wa(bstr, exval), "value=%s\n", wine_dbgstr_w(bstr));
1914     else
1915         ok_(__FILE__,line) (!exval, "exval != NULL\n");
1916     SysFreeString(bstr);
1917     IHTMLInputElement_Release(input);
1918 }
1919
1920 #define test_input_put_value(o,v) _test_input_put_value(__LINE__,o,v)
1921 static void _test_input_put_value(unsigned line, IUnknown *unk, const char *val)
1922 {
1923     IHTMLInputElement *input;
1924     BSTR bstr;
1925     HRESULT hres;
1926
1927     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
1928     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
1929     if(FAILED(hres))
1930         return;
1931
1932     bstr = a2bstr(val);
1933     hres = IHTMLInputElement_get_value(input, &bstr);
1934     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1935     SysFreeString(bstr);
1936     IHTMLInputElement_Release(input);
1937 }
1938
1939 #define test_input_src(i,s) _test_input_src(__LINE__,i,s)
1940 static void _test_input_src(unsigned line, IHTMLInputElement *input, const char *exsrc)
1941 {
1942     BSTR src;
1943     HRESULT hres;
1944
1945     hres = IHTMLInputElement_get_src(input, &src);
1946     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
1947     if(exsrc)
1948         ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
1949     else
1950         ok_(__FILE__,line) (!src, "get_src returned %s expected NULL\n", wine_dbgstr_w(src));
1951     SysFreeString(src);
1952 }
1953
1954 #define test_input_set_src(u,s) _test_input_set_src(__LINE__,u,s)
1955 static void _test_input_set_src(unsigned line, IHTMLInputElement *input, const char *src)
1956 {
1957     BSTR tmp;
1958     HRESULT hres;
1959
1960     tmp = a2bstr(src);
1961     hres = IHTMLInputElement_put_src(input, tmp);
1962     SysFreeString(tmp);
1963     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
1964
1965     _test_input_src(line, input, src);
1966 }
1967
1968 #define test_elem_class(u,c) _test_elem_class(__LINE__,u,c)
1969 static void _test_elem_class(unsigned line, IUnknown *unk, const char *exclass)
1970 {
1971     IHTMLElement *elem = _get_elem_iface(line, unk);
1972     BSTR class = (void*)0xdeadbeef;
1973     HRESULT hres;
1974
1975     hres = IHTMLElement_get_className(elem, &class);
1976     IHTMLElement_Release(elem);
1977     ok_(__FILE__,line) (hres == S_OK, "get_className failed: %08x\n", hres);
1978     if(exclass)
1979         ok_(__FILE__,line) (!strcmp_wa(class, exclass), "unexpected className %s\n", wine_dbgstr_w(class));
1980     else
1981         ok_(__FILE__,line) (!class, "class != NULL\n");
1982     SysFreeString(class);
1983 }
1984
1985 #define test_elem_tabindex(u,i) _test_elem_tabindex(__LINE__,u,i)
1986 static void _test_elem_tabindex(unsigned line, IUnknown *unk, short exindex)
1987 {
1988     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
1989     short index = -3;
1990     HRESULT hres;
1991
1992     hres = IHTMLElement2_get_tabIndex(elem2, &index);
1993     IHTMLElement2_Release(elem2);
1994     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
1995     ok_(__FILE__,line) (index == exindex, "unexpected index %d\n", index);
1996 }
1997
1998 #define test_elem_set_tabindex(u,i) _test_elem_set_tabindex(__LINE__,u,i)
1999 static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index)
2000 {
2001     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
2002     HRESULT hres;
2003
2004     hres = IHTMLElement2_put_tabIndex(elem2, index);
2005     IHTMLElement2_Release(elem2);
2006     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
2007
2008     _test_elem_tabindex(line, unk, index);
2009 }
2010
2011 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
2012 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
2013 {
2014     IHTMLElement *elem = _get_elem_iface(line, unk);
2015     BSTR tmp;
2016     HRESULT hres;
2017
2018     tmp = class ? a2bstr(class) : NULL;
2019     hres = IHTMLElement_put_className(elem, tmp);
2020     IHTMLElement_Release(elem);
2021     ok_(__FILE__,line) (hres == S_OK, "put_className failed: %08x\n", hres);
2022     SysFreeString(tmp);
2023
2024     _test_elem_class(line, unk, class);
2025 }
2026
2027 #define test_elem_id(e,i) _test_elem_id(__LINE__,e,i)
2028 static void _test_elem_id(unsigned line, IUnknown *unk, const char *exid)
2029 {
2030     IHTMLElement *elem = _get_elem_iface(line, unk);
2031     BSTR id = (void*)0xdeadbeef;
2032     HRESULT hres;
2033
2034     hres = IHTMLElement_get_id(elem, &id);
2035     IHTMLElement_Release(elem);
2036     ok_(__FILE__,line) (hres == S_OK, "get_id failed: %08x\n", hres);
2037
2038     if(exid)
2039         ok_(__FILE__,line) (!strcmp_wa(id, exid), "unexpected id %s\n", wine_dbgstr_w(id));
2040     else
2041         ok_(__FILE__,line) (!id, "id=%s\n", wine_dbgstr_w(id));
2042
2043     SysFreeString(id);
2044 }
2045
2046 #define test_elem_put_id(u,i) _test_elem_put_id(__LINE__,u,i)
2047 static void _test_elem_put_id(unsigned line, IUnknown *unk, const char *new_id)
2048 {
2049     IHTMLElement *elem = _get_elem_iface(line, unk);
2050     BSTR tmp = a2bstr(new_id);
2051     HRESULT hres;
2052
2053     hres = IHTMLElement_put_id(elem, tmp);
2054     IHTMLElement_Release(elem);
2055     SysFreeString(tmp);
2056     ok_(__FILE__,line) (hres == S_OK, "put_id failed: %08x\n", hres);
2057
2058     _test_elem_id(line, unk, new_id);
2059 }
2060
2061 #define test_elem_title(u,t) _test_elem_title(__LINE__,u,t)
2062 static void _test_elem_title(unsigned line, IUnknown *unk, const char *extitle)
2063 {
2064     IHTMLElement *elem = _get_elem_iface(line, unk);
2065     BSTR title;
2066     HRESULT hres;
2067
2068     hres = IHTMLElement_get_title(elem, &title);
2069     IHTMLElement_Release(elem);
2070     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2071     if(extitle)
2072         ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
2073     else
2074         ok_(__FILE__,line) (!title, "title=%s, expected NULL\n", wine_dbgstr_w(title));
2075
2076     SysFreeString(title);
2077 }
2078
2079 #define test_elem_set_title(u,t) _test_elem_set_title(__LINE__,u,t)
2080 static void _test_elem_set_title(unsigned line, IUnknown *unk, const char *title)
2081 {
2082     IHTMLElement *elem = _get_elem_iface(line, unk);
2083     BSTR tmp;
2084     HRESULT hres;
2085
2086     tmp = a2bstr(title);
2087     hres = IHTMLElement_put_title(elem, tmp);
2088     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2089
2090     IHTMLElement_Release(elem);
2091     SysFreeString(tmp);
2092 }
2093
2094 #define test_node_get_value_str(u,e) _test_node_get_value_str(__LINE__,u,e)
2095 static void _test_node_get_value_str(unsigned line, IUnknown *unk, const char *exval)
2096 {
2097     IHTMLDOMNode *node = _get_node_iface(line, unk);
2098     VARIANT var;
2099     HRESULT hres;
2100
2101     hres = IHTMLDOMNode_get_nodeValue(node, &var);
2102     IHTMLDOMNode_Release(node);
2103     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
2104
2105     if(exval) {
2106         ok_(__FILE__,line) (V_VT(&var) == VT_BSTR, "vt=%d\n", V_VT(&var));
2107         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&var), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&var)));
2108     }else {
2109         ok_(__FILE__,line) (V_VT(&var) == VT_NULL, "vt=%d, expected VT_NULL\n", V_VT(&var));
2110     }
2111
2112     VariantClear(&var);
2113 }
2114
2115 #define test_node_put_value_str(u,v) _test_node_put_value_str(__LINE__,u,v)
2116 static void _test_node_put_value_str(unsigned line, IUnknown *unk, const char *val)
2117 {
2118     IHTMLDOMNode *node = _get_node_iface(line, unk);
2119     VARIANT var;
2120     HRESULT hres;
2121
2122     V_VT(&var) = VT_BSTR;
2123     V_BSTR(&var) = a2bstr(val);
2124
2125     hres = IHTMLDOMNode_put_nodeValue(node, var);
2126     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
2127     IHTMLDOMNode_Release(node);
2128     VariantClear(&var);
2129 }
2130
2131 #define test_elem_client_size(u) _test_elem_client_size(__LINE__,u)
2132 static void _test_elem_client_size(unsigned line, IUnknown *unk)
2133 {
2134     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2135     LONG l;
2136     HRESULT hres;
2137
2138     hres = IHTMLElement2_get_clientWidth(elem, &l);
2139     ok_(__FILE__,line) (hres == S_OK, "get_clientWidth failed: %08x\n", hres);
2140     hres = IHTMLElement2_get_clientHeight(elem, &l);
2141     ok_(__FILE__,line) (hres == S_OK, "get_clientHeight failed: %08x\n", hres);
2142
2143     IHTMLElement2_Release(elem);
2144 }
2145
2146 #define test_elem_client_rect(u) _test_elem_client_rect(__LINE__,u)
2147 static void _test_elem_client_rect(unsigned line, IUnknown *unk)
2148 {
2149     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2150     LONG l;
2151     HRESULT hres;
2152
2153     hres = IHTMLElement2_get_clientLeft(elem, &l);
2154     ok_(__FILE__,line) (hres == S_OK, "get_clientLeft failed: %08x\n", hres);
2155     ok_(__FILE__,line) (!l, "clientLeft = %d\n", l);
2156
2157     hres = IHTMLElement2_get_clientTop(elem, &l);
2158     ok_(__FILE__,line) (hres == S_OK, "get_clientTop failed: %08x\n", hres);
2159     ok_(__FILE__,line) (!l, "clientTop = %d\n", l);
2160
2161     IHTMLElement2_Release(elem);
2162 }
2163
2164 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
2165 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
2166 {
2167     IHTMLElement *elem = NULL;
2168     BSTR tmp;
2169     HRESULT hres;
2170
2171     tmp = a2bstr(tag);
2172     hres = IHTMLDocument2_createElement(doc, tmp, &elem);
2173     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
2174     ok_(__FILE__,line) (elem != NULL, "elem == NULL\n");
2175
2176     return elem;
2177 }
2178
2179 #define test_create_text(d,t) _test_create_text(__LINE__,d,t)
2180 static IHTMLDOMNode *_test_create_text(unsigned line, IHTMLDocument2 *doc, const char *text)
2181 {
2182     IHTMLDocument3 *doc3;
2183     IHTMLDOMNode *node = NULL;
2184     BSTR tmp;
2185     HRESULT hres;
2186
2187     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
2188     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3: %08x\n", hres);
2189
2190     tmp = a2bstr(text);
2191     hres = IHTMLDocument3_createTextNode(doc3, tmp, &node);
2192     IHTMLDocument3_Release(doc3);
2193     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
2194     ok_(__FILE__,line) (node != NULL, "node == NULL\n");
2195
2196     return node;
2197 }
2198
2199 #define test_node_append_child(n,c) _test_node_append_child(__LINE__,n,c)
2200 static IHTMLDOMNode *_test_node_append_child(unsigned line, IUnknown *node_unk, IUnknown *child_unk)
2201 {
2202     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
2203     IHTMLDOMNode *child = _get_node_iface(line, child_unk);
2204     IHTMLDOMNode *new_child = NULL;
2205     HRESULT hres;
2206
2207     hres = IHTMLDOMNode_appendChild(node, child, &new_child);
2208     ok_(__FILE__,line) (hres == S_OK, "appendChild failed: %08x\n", hres);
2209     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
2210     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
2211
2212     IHTMLDOMNode_Release(node);
2213     IHTMLDOMNode_Release(child);
2214
2215     return new_child;
2216 }
2217
2218 #define test_node_insertbefore(n,c,v) _test_node_insertbefore(__LINE__,n,c,v)
2219 static IHTMLDOMNode *_test_node_insertbefore(unsigned line, IUnknown *node_unk, IHTMLDOMNode *child, VARIANT *var)
2220 {
2221     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
2222     IHTMLDOMNode *new_child = NULL;
2223     HRESULT hres;
2224
2225     hres = IHTMLDOMNode_insertBefore(node, child, *var, &new_child);
2226     ok_(__FILE__,line) (hres == S_OK, "insertBefore failed: %08x\n", hres);
2227     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
2228     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
2229
2230     IHTMLDOMNode_Release(node);
2231
2232     return new_child;
2233 }
2234
2235 #define test_node_remove_child(n,c) _test_node_remove_child(__LINE__,n,c)
2236 static void _test_node_remove_child(unsigned line, IUnknown *unk, IHTMLDOMNode *child)
2237 {
2238     IHTMLDOMNode *node = _get_node_iface(line, unk);
2239     IHTMLDOMNode *new_node = NULL;
2240     HRESULT hres;
2241
2242     hres = IHTMLDOMNode_removeChild(node, child, &new_node);
2243     ok_(__FILE__,line) (hres == S_OK, "removeChild failed: %08x\n", hres);
2244     ok_(__FILE__,line) (new_node != NULL, "new_node == NULL\n");
2245     /* TODO ok_(__FILE__,line) (new_node != child, "new_node == child\n"); */
2246
2247     IHTMLDOMNode_Release(node);
2248     IHTMLDOMNode_Release(new_node);
2249 }
2250
2251 #define test_doc_title(d,t) _test_doc_title(__LINE__,d,t)
2252 static void _test_doc_title(unsigned line, IHTMLDocument2 *doc, const char *extitle)
2253 {
2254     BSTR title = NULL;
2255     HRESULT hres;
2256
2257     hres = IHTMLDocument2_get_title(doc, &title);
2258     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2259     ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
2260     SysFreeString(title);
2261 }
2262
2263 #define test_doc_set_title(d,t) _test_doc_set_title(__LINE__,d,t)
2264 static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *title)
2265 {
2266     BSTR tmp;
2267     HRESULT hres;
2268
2269     tmp = a2bstr(title);
2270     hres = IHTMLDocument2_put_title(doc, tmp);
2271     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2272     SysFreeString(tmp);
2273 }
2274
2275 #define test_border_styles(p, n) _test_border_styles(__LINE__, p, n)
2276 static void _test_border_styles(unsigned line, IHTMLStyle *pStyle, BSTR Name)
2277 {
2278     HRESULT hres;
2279     DISPID dispid;
2280
2281     hres = IHTMLStyle_GetIDsOfNames(pStyle, &IID_NULL, &Name, 1,
2282                         LOCALE_USER_DEFAULT, &dispid);
2283     ok_(__FILE__,line) (hres == S_OK, "GetIDsOfNames: %08x\n", hres);
2284     if(hres == S_OK)
2285     {
2286         DISPPARAMS params = {NULL,NULL,0,0};
2287         DISPID dispidNamed = DISPID_PROPERTYPUT;
2288         VARIANT ret;
2289         VARIANT vDefault;
2290         VARIANTARG arg;
2291
2292         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2293             DISPATCH_PROPERTYGET, &params, &vDefault, NULL, NULL);
2294         ok_(__FILE__,line) (hres == S_OK, "get_default. ret: %08x\n", hres);
2295
2296         params.cArgs = 1;
2297         params.cNamedArgs = 1;
2298         params.rgdispidNamedArgs = &dispidNamed;
2299         V_VT(&arg) = VT_BSTR;
2300         V_BSTR(&arg) = a2bstr("none");
2301         params.rgvarg = &arg;
2302         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2303             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2304         ok_(__FILE__,line) (hres == S_OK, "none. ret: %08x\n", hres);
2305         VariantClear(&arg);
2306
2307         V_VT(&arg) = VT_BSTR;
2308         V_BSTR(&arg) = a2bstr("dotted");
2309         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2310             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2311         ok_(__FILE__,line) (hres == S_OK, "dotted. ret: %08x\n", hres);
2312         VariantClear(&arg);
2313
2314         V_VT(&arg) = VT_BSTR;
2315         V_BSTR(&arg) = a2bstr("dashed");
2316         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2317         DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2318         ok_(__FILE__,line) (hres == S_OK, "dashed. ret: %08x\n", hres);
2319         VariantClear(&arg);
2320
2321         V_VT(&arg) = VT_BSTR;
2322         V_BSTR(&arg) = a2bstr("solid");
2323         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2324             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2325         ok_(__FILE__,line) (hres == S_OK, "solid. ret: %08x\n", hres);
2326         VariantClear(&arg);
2327
2328         V_VT(&arg) = VT_BSTR;
2329         V_BSTR(&arg) = a2bstr("double");
2330         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2331             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2332         ok_(__FILE__,line) (hres == S_OK, "double. ret: %08x\n", hres);
2333         VariantClear(&arg);
2334
2335         V_VT(&arg) = VT_BSTR;
2336         V_BSTR(&arg) = a2bstr("groove");
2337         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2338             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2339         ok_(__FILE__,line) (hres == S_OK, "groove. ret: %08x\n", hres);
2340         VariantClear(&arg);
2341
2342         V_VT(&arg) = VT_BSTR;
2343         V_BSTR(&arg) = a2bstr("ridge");
2344         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2345             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2346         ok_(__FILE__,line) (hres == S_OK, "ridge. ret: %08x\n", hres);
2347         VariantClear(&arg);
2348
2349         V_VT(&arg) = VT_BSTR;
2350         V_BSTR(&arg) = a2bstr("inset");
2351         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2352             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2353         ok_(__FILE__,line) (hres == S_OK, "inset. ret: %08x\n", hres);
2354         VariantClear(&arg);
2355
2356         V_VT(&arg) = VT_BSTR;
2357         V_BSTR(&arg) = a2bstr("outset");
2358         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2359             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2360         ok_(__FILE__,line) (hres == S_OK, "outset. ret: %08x\n", hres);
2361         VariantClear(&arg);
2362
2363         V_VT(&arg) = VT_BSTR;
2364         V_BSTR(&arg) = a2bstr("invalid");
2365         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2366             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2367         ok_(__FILE__,line) (FAILED(hres), "invalid value passed.\n");
2368         VariantClear(&arg);
2369
2370         params.rgvarg = &vDefault;
2371         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2372             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2373         ok_(__FILE__,line) (hres == S_OK, "default. ret: %08x\n", hres);
2374     }
2375 }
2376
2377 #define test_style_csstext(s,t) _test_style_csstext(__LINE__,s,t)
2378 static void _test_style_csstext(unsigned line, IHTMLStyle *style, const char *extext)
2379 {
2380     BSTR text = (void*)0xdeadbeef;
2381     HRESULT hres;
2382
2383     hres = IHTMLStyle_get_cssText(style, &text);
2384     ok_(__FILE__,line)(hres == S_OK, "get_cssText failed: %08x\n", hres);
2385     if(extext)
2386         ok_(__FILE__,line)(!strcmp_wa(text, extext), "cssText = %s\n", wine_dbgstr_w(text));
2387     else
2388         ok_(__FILE__,line)(!text, "cssText = %s\n", wine_dbgstr_w(text));
2389
2390     SysFreeString(text);
2391 }
2392
2393 #define test_style_set_csstext(s,t) _test_style_set_csstext(__LINE__,s,t)
2394 static void _test_style_set_csstext(unsigned line, IHTMLStyle *style, const char *text)
2395 {
2396     BSTR tmp;
2397     HRESULT hres;
2398
2399     tmp = a2bstr(text);
2400     hres = IHTMLStyle_put_cssText(style, tmp);
2401     ok_(__FILE__,line)(hres == S_OK, "put_cssText failed: %08x\n", hres);
2402     SysFreeString(tmp);
2403 }
2404
2405 static void test_elem_col_item(IHTMLElementCollection *col, const char *n,
2406         const elem_type_t *elem_types, LONG len)
2407 {
2408     IDispatch *disp;
2409     VARIANT name, index;
2410     DWORD i;
2411     HRESULT hres;
2412
2413     V_VT(&index) = VT_EMPTY;
2414     V_VT(&name) = VT_BSTR;
2415     V_BSTR(&name) = a2bstr(n);
2416
2417     hres = IHTMLElementCollection_item(col, name, index, &disp);
2418     ok(hres == S_OK, "item failed: %08x\n", hres);
2419
2420     test_elem_collection((IUnknown*)disp, elem_types, len);
2421     IDispatch_Release(disp);
2422     ok(hres == S_OK, "Could not get IHTMLElementCollection interface: %08x\n", hres);
2423     if(hres != S_OK)
2424         goto cleanup;
2425
2426     V_VT(&index) = VT_I4;
2427
2428     for(i=0; i<len; i++) {
2429         V_I4(&index) = i;
2430         disp = (void*)0xdeadbeef;
2431         hres = IHTMLElementCollection_item(col, name, index, &disp);
2432         ok(hres == S_OK, "item failed: %08x\n", hres);
2433         ok(disp != NULL, "disp == NULL\n");
2434         if(FAILED(hres) || !disp)
2435             continue;
2436
2437         test_elem_type((IUnknown*)disp, elem_types[i]);
2438
2439         IDispatch_Release(disp);
2440     }
2441
2442     V_I4(&index) = len;
2443     disp = (void*)0xdeadbeef;
2444     hres = IHTMLElementCollection_item(col, name, index, &disp);
2445     ok(hres == S_OK, "item failed: %08x\n", hres);
2446     ok(disp == NULL, "disp != NULL\n");
2447
2448     V_I4(&index) = -1;
2449     disp = (void*)0xdeadbeef;
2450     hres = IHTMLElementCollection_item(col, name, index, &disp);
2451     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
2452     ok(disp == NULL, "disp != NULL\n");
2453
2454 cleanup:
2455     SysFreeString(V_BSTR(&name));
2456 }
2457
2458 static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const char *id, BOOL expect_success)
2459 {
2460     IHTMLElementCollection *col;
2461     IHTMLElement *elem;
2462     IDispatch *disp = (void*)0xdeadbeef;
2463     VARIANT name, index;
2464     HRESULT hres;
2465
2466     hres = IHTMLDocument2_get_all(doc, &col);
2467     ok(hres == S_OK, "get_all failed: %08x\n", hres);
2468     ok(col != NULL, "col == NULL\n");
2469     if(FAILED(hres) || !col)
2470         return NULL;
2471
2472     V_VT(&index) = VT_EMPTY;
2473     V_VT(&name) = VT_BSTR;
2474     V_BSTR(&name) = a2bstr(id);
2475
2476     hres = IHTMLElementCollection_item(col, name, index, &disp);
2477     IHTMLElementCollection_Release(col);
2478     SysFreeString(V_BSTR(&name));
2479     ok(hres == S_OK, "item failed: %08x\n", hres);
2480     if(!expect_success) {
2481         ok(disp == NULL, "disp != NULL\n");
2482         return NULL;
2483     }
2484
2485     ok(disp != NULL, "disp == NULL\n");
2486     if(!disp)
2487         return NULL;
2488
2489     elem = get_elem_iface((IUnknown*)disp);
2490     IDispatch_Release(disp);
2491
2492     return elem;
2493 }
2494
2495 static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const char *id)
2496 {
2497     IHTMLDocument3 *doc3;
2498     IHTMLElement *elem;
2499     BSTR tmp;
2500     HRESULT hres;
2501
2502     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
2503     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
2504
2505     tmp = a2bstr(id);
2506     hres = IHTMLDocument3_getElementById(doc3, tmp, &elem);
2507     SysFreeString(tmp);
2508     ok(hres == S_OK, "getElementById(%s) failed: %08x\n", id, hres);
2509
2510     IHTMLDocument3_Release(doc3);
2511
2512     return elem;
2513 }
2514
2515 static void test_select_elem(IHTMLSelectElement *select)
2516 {
2517     test_select_type(select, "select-one");
2518     test_select_length(select, 2);
2519     test_select_selidx(select, 0);
2520     test_select_put_selidx(select, 1);
2521
2522     test_select_set_value(select, "val1");
2523     test_select_value(select, "val1");
2524
2525     test_select_get_disabled(select, VARIANT_FALSE);
2526     test_select_set_disabled(select, VARIANT_TRUE);
2527     test_select_set_disabled(select, VARIANT_FALSE);
2528 }
2529
2530 static void test_create_option_elem(IHTMLDocument2 *doc)
2531 {
2532     IHTMLOptionElement *option;
2533
2534     option = create_option_elem(doc, "test text", "test value");
2535
2536     test_option_put_text(option, "new text");
2537     test_option_put_value(option, "new value");
2538
2539     IHTMLOptionElement_Release(option);
2540 }
2541
2542 static void test_create_img_elem(IHTMLDocument2 *doc)
2543 {
2544     IHTMLImgElement *img;
2545
2546     img = create_img_elem(doc, 10, 15);
2547
2548     if(img){
2549         test_img_put_width(img, 5);
2550         test_img_put_height(img, 20);
2551
2552         IHTMLImgElement_Release(img);
2553         img = NULL;
2554     }
2555
2556     img = create_img_elem(doc, -1, -1);
2557
2558     if(img){
2559         test_img_put_width(img, 5);
2560         test_img_put_height(img, 20);
2561
2562         IHTMLImgElement_Release(img);
2563     }
2564 }
2565
2566 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
2567 {
2568     IHTMLBodyElement *body;
2569     IHTMLTxtRange *range;
2570     IHTMLElement *elem;
2571     HRESULT hres;
2572
2573     hres = IHTMLDocument2_get_body(doc, &elem);
2574     ok(hres == S_OK, "get_body failed: %08x\n", hres);
2575
2576     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
2577     IHTMLElement_Release(elem);
2578
2579     hres = IHTMLBodyElement_createTextRange(body, &range);
2580     IHTMLBodyElement_Release(body);
2581     ok(hres == S_OK, "createTextRange failed: %08x\n", hres);
2582
2583     return range;
2584 }
2585
2586 static void test_txtrange(IHTMLDocument2 *doc)
2587 {
2588     IHTMLTxtRange *body_range, *range, *range2;
2589     IHTMLSelectionObject *selection;
2590     IDispatch *disp_range;
2591     HRESULT hres;
2592
2593     body_range = test_create_body_range(doc);
2594
2595     test_range_text(body_range, "test abc 123\r\nit's text");
2596
2597     hres = IHTMLTxtRange_duplicate(body_range, &range);
2598     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2599
2600     hres = IHTMLTxtRange_duplicate(body_range, &range2);
2601     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2602     test_range_isequal(range, range2, VARIANT_TRUE);
2603
2604     test_range_text(range, "test abc 123\r\nit's text");
2605     test_range_text(body_range, "test abc 123\r\nit's text");
2606
2607     test_range_collapse(range, TRUE);
2608     test_range_isequal(range, range2, VARIANT_FALSE);
2609     test_range_inrange(range, range2, VARIANT_FALSE);
2610     test_range_inrange(range2, range, VARIANT_TRUE);
2611     IHTMLTxtRange_Release(range2);
2612
2613     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
2614     test_range_expand(range, wordW, VARIANT_FALSE, "test ");
2615     test_range_move(range, characterW, 2, 2);
2616     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
2617
2618     test_range_collapse(range, FALSE);
2619     test_range_expand(range, wordW, VARIANT_TRUE, "abc ");
2620
2621     test_range_collapse(range, FALSE);
2622     test_range_expand(range, wordW, VARIANT_TRUE, "123");
2623     test_range_expand(range, wordW, VARIANT_FALSE, "123");
2624     test_range_move(range, characterW, 2, 2);
2625     test_range_expand(range, wordW, VARIANT_TRUE, "123");
2626     test_range_moveend(range, characterW, -5, -5);
2627     test_range_text(range, NULL);
2628     test_range_moveend(range, characterW, 3, 3);
2629     test_range_text(range, "c 1");
2630     test_range_expand(range, texteditW, VARIANT_TRUE, "test abc 123\r\nit's text");
2631     test_range_collapse(range, TRUE);
2632     test_range_move(range, characterW, 4, 4);
2633     test_range_moveend(range, characterW, 1, 1);
2634     test_range_text(range, " ");
2635     test_range_move(range, wordW, 1, 1);
2636     test_range_moveend(range, characterW, 2, 2);
2637     test_range_text(range, "ab");
2638
2639     IHTMLTxtRange_Release(range);
2640
2641     hres = IHTMLTxtRange_duplicate(body_range, &range);
2642     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2643
2644     test_range_text(range, "test abc 123\r\nit's text");
2645     test_range_move(range, characterW, 3, 3);
2646     test_range_moveend(range, characterW, 1, 1);
2647     test_range_text(range, "t");
2648     test_range_moveend(range, characterW, 3, 3);
2649     test_range_text(range, "t ab");
2650     test_range_moveend(range, characterW, -2, -2);
2651     test_range_text(range, "t ");
2652     test_range_move(range, characterW, 6, 6);
2653     test_range_moveend(range, characterW, 3, 3);
2654     test_range_text(range, "123");
2655     test_range_moveend(range, characterW, 2, 2);
2656     test_range_text(range, "123\r\ni");
2657
2658     IHTMLTxtRange_Release(range);
2659
2660     hres = IHTMLTxtRange_duplicate(body_range, &range);
2661     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2662
2663     test_range_move(range, wordW, 1, 1);
2664     test_range_moveend(range, characterW, 2, 2);
2665     test_range_text(range, "ab");
2666
2667     test_range_move(range, characterW, -2, -2);
2668     test_range_moveend(range, characterW, 2, 2);
2669     test_range_text(range, "t ");
2670
2671     test_range_move(range, wordW, 3, 3);
2672     test_range_move(range, wordW, -2, -2);
2673     test_range_moveend(range, characterW, 2, 2);
2674     test_range_text(range, "ab");
2675
2676     test_range_move(range, characterW, -6, -5);
2677     test_range_moveend(range, characterW, -1, 0);
2678     test_range_moveend(range, characterW, -6, 0);
2679     test_range_move(range, characterW, 2, 2);
2680     test_range_moveend(range, characterW, 2, 2);
2681     test_range_text(range, "st");
2682     test_range_moveend(range, characterW, -6, -4);
2683     test_range_moveend(range, characterW, 2, 2);
2684
2685     IHTMLTxtRange_Release(range);
2686
2687     hres = IHTMLTxtRange_duplicate(body_range, &range);
2688     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2689
2690     test_range_move(range, wordW, 2, 2);
2691     test_range_moveend(range, characterW, 2, 2);
2692     test_range_text(range, "12");
2693
2694     test_range_move(range, characterW, 15, 14);
2695     test_range_move(range, characterW, -2, -2);
2696     test_range_moveend(range, characterW, 3, 2);
2697     test_range_text(range, "t");
2698     test_range_moveend(range, characterW, -1, -1);
2699     test_range_text(range, "t");
2700     test_range_expand(range, wordW, VARIANT_TRUE, "text");
2701     test_range_move(range, characterW, -2, -2);
2702     test_range_moveend(range, characterW, 2, 2);
2703     test_range_text(range, "s ");
2704     test_range_move(range, characterW, 100, 7);
2705     test_range_move(range, wordW, 1, 0);
2706     test_range_move(range, characterW, -2, -2);
2707     test_range_moveend(range, characterW, 3, 2);
2708     test_range_text(range, "t");
2709
2710     IHTMLTxtRange_Release(range);
2711
2712     hres = IHTMLTxtRange_duplicate(body_range, &range);
2713     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2714
2715     test_range_collapse(range, TRUE);
2716     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
2717     test_range_put_text(range, "word");
2718     test_range_text(body_range, "wordabc 123\r\nit's text");
2719     test_range_text(range, NULL);
2720     test_range_moveend(range, characterW, 3, 3);
2721     test_range_text(range, "abc");
2722     test_range_movestart(range, characterW, -2, -2);
2723     test_range_text(range, "rdabc");
2724     test_range_movestart(range, characterW, 3, 3);
2725     test_range_text(range, "bc");
2726     test_range_movestart(range, characterW, 4, 4);
2727     test_range_text(range, NULL);
2728     test_range_movestart(range, characterW, -3, -3);
2729     test_range_text(range, "c 1");
2730     test_range_movestart(range, characterW, -7, -6);
2731     test_range_text(range, "wordabc 1");
2732     test_range_movestart(range, characterW, 100, 22);
2733     test_range_text(range, NULL);
2734
2735     IHTMLTxtRange_Release(range);
2736     IHTMLTxtRange_Release(body_range);
2737
2738     hres = IHTMLDocument2_get_selection(doc, &selection);
2739     ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres);
2740
2741     hres = IHTMLSelectionObject_createRange(selection, &disp_range);
2742     ok(hres == S_OK, "IHTMLSelectionObject_createRange failed: %08x\n", hres);
2743     IHTMLSelectionObject_Release(selection);
2744
2745     hres = IDispatch_QueryInterface(disp_range, &IID_IHTMLTxtRange, (void **)&range);
2746     ok(hres == S_OK, "Could not get IID_IHTMLTxtRange interface: 0x%08x\n", hres);
2747     IDispatch_Release(disp_range);
2748
2749     test_range_text(range, NULL);
2750     test_range_moveend(range, characterW, 3, 3);
2751     test_range_text(range, "wor");
2752     test_range_parent(range, ET_BODY);
2753     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
2754     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
2755     test_range_move(range, characterW, 3, 3);
2756     test_range_expand(range, wordW, VARIANT_TRUE, "wordabc ");
2757     test_range_moveend(range, characterW, -4, -4);
2758     test_range_put_text(range, "abc def ");
2759     test_range_expand(range, texteditW, VARIANT_TRUE, "abc def abc 123\r\nit's text");
2760     test_range_move(range, wordW, 1, 1);
2761     test_range_movestart(range, characterW, -1, -1);
2762     test_range_text(range, " ");
2763     test_range_move(range, wordW, 1, 1);
2764     test_range_moveend(range, characterW, 3, 3);
2765     test_range_text(range, "def");
2766     test_range_put_text(range, "xyz");
2767     test_range_moveend(range, characterW, 1, 1);
2768     test_range_move(range, wordW, 1, 1);
2769     test_range_moveend(range, characterW, 2, 2);
2770     test_range_text(range, "ab");
2771
2772     IHTMLTxtRange_Release(range);
2773 }
2774
2775 static void test_txtrange2(IHTMLDocument2 *doc)
2776 {
2777     IHTMLTxtRange *range;
2778
2779     range = test_create_body_range(doc);
2780
2781     test_range_text(range, "abc\r\n\r\n123\r\n\r\n\r\ndef");
2782     test_range_move(range, characterW, 5, 5);
2783     test_range_moveend(range, characterW, 1, 1);
2784     test_range_text(range, "2");
2785     test_range_move(range, characterW, -3, -3);
2786     test_range_moveend(range, characterW, 3, 3);
2787     test_range_text(range, "c\r\n\r\n1");
2788     test_range_collapse(range, VARIANT_FALSE);
2789     test_range_moveend(range, characterW, 4, 4);
2790     test_range_text(range, "23");
2791     test_range_moveend(range, characterW, 1, 1);
2792     test_range_text(range, "23\r\n\r\n\r\nd");
2793     test_range_moveend(range, characterW, -1, -1);
2794     test_range_text(range, "23");
2795     test_range_moveend(range, characterW, -1, -1);
2796     test_range_text(range, "23");
2797     test_range_moveend(range, characterW, -2, -2);
2798     test_range_text(range, "2");
2799
2800     IHTMLTxtRange_Release(range);
2801 }
2802
2803 static void test_compatmode(IHTMLDocument2 *doc)
2804 {
2805     IHTMLDocument5 *doc5;
2806     BSTR mode;
2807     HRESULT hres;
2808
2809     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
2810     ok(hres == S_OK, "Could not get IHTMLDocument5 interface: %08x\n", hres);
2811     if(FAILED(hres))
2812         return;
2813
2814     hres = IHTMLDocument5_get_compatMode(doc5, &mode);
2815     IHTMLDocument5_Release(doc5);
2816     ok(hres == S_OK, "get_compatMode failed: %08x\n", hres);
2817     ok(!strcmp_wa(mode, "BackCompat"), "compatMode=%s\n", wine_dbgstr_w(mode));
2818     SysFreeString(mode);
2819 }
2820
2821 static void test_location(IHTMLDocument2 *doc)
2822 {
2823     IHTMLLocation *location, *location2;
2824     IHTMLWindow2 *window;
2825     BSTR str;
2826     ULONG ref;
2827     HRESULT hres;
2828
2829     hres = IHTMLDocument2_get_location(doc, &location);
2830     ok(hres == S_OK, "get_location failed: %08x\n", hres);
2831
2832     hres = IHTMLDocument2_get_location(doc, &location2);
2833     ok(hres == S_OK, "get_location failed: %08x\n", hres);
2834
2835     ok(location == location2, "location != location2\n");
2836     IHTMLLocation_Release(location2);
2837
2838     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2839     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
2840
2841     hres = IHTMLWindow2_get_location(window, &location2);
2842     ok(hres == S_OK, "get_location failed: %08x\n", hres);
2843     ok(location == location2, "location != location2\n");
2844     IHTMLLocation_Release(location2);
2845
2846     test_ifaces((IUnknown*)location, location_iids);
2847     test_disp2((IUnknown*)location, &DIID_DispHTMLLocation, &IID_IHTMLLocation, "about:blank");
2848
2849     hres = IHTMLLocation_get_pathname(location, &str);
2850     ok(hres == S_OK, "get_pathname failed: %08x\n", hres);
2851     ok(!strcmp_wa(str, "blank"), "unexpected pathname %s\n", wine_dbgstr_w(str));
2852
2853     hres = IHTMLLocation_get_href(location, NULL);
2854     ok(hres == E_POINTER, "get_href passed: %08x\n", hres);
2855
2856     hres = IHTMLLocation_get_href(location, &str);
2857     ok(hres == S_OK, "get_href failed: %08x\n", hres);
2858     ok(!strcmp_wa(str, "about:blank"), "unexpected href %s\n", wine_dbgstr_w(str));
2859
2860     ref = IHTMLLocation_Release(location);
2861     ok(!ref, "location chould be destroyed here\n");
2862 }
2863
2864 static void test_navigator(IHTMLDocument2 *doc)
2865 {
2866     IHTMLWindow2 *window;
2867     IOmNavigator *navigator, *navigator2;
2868     char buf[512];
2869     DWORD size;
2870     ULONG ref;
2871     BSTR bstr;
2872     HRESULT hres;
2873
2874     static const WCHAR v40[] = {'4','.','0'};
2875
2876     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2877     ok(hres == S_OK, "parentWidnow failed: %08x\n", hres);
2878
2879     hres = IHTMLWindow2_get_navigator(window, &navigator);
2880     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
2881     ok(navigator != NULL, "navigator == NULL\n");
2882     test_disp2((IUnknown*)navigator, &DIID_DispHTMLNavigator, &IID_IOmNavigator, "[object]");
2883
2884     hres = IHTMLWindow2_get_navigator(window, &navigator2);
2885     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
2886     ok(navigator != navigator2, "navigator2 != navihgator\n");
2887
2888     IHTMLWindow2_Release(window);
2889     IOmNavigator_Release(navigator2);
2890
2891     hres = IOmNavigator_get_appCodeName(navigator, &bstr);
2892     ok(hres == S_OK, "get_appCodeName failed: %08x\n", hres);
2893     ok(!strcmp_wa(bstr, "Mozilla"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
2894     SysFreeString(bstr);
2895
2896     bstr = NULL;
2897     hres = IOmNavigator_get_appName(navigator, &bstr);
2898     ok(hres == S_OK, "get_appName failed: %08x\n", hres);
2899     ok(!strcmp_wa(bstr, "Microsoft Internet Explorer"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
2900     SysFreeString(bstr);
2901
2902     bstr = NULL;
2903     hres = IOmNavigator_get_platform(navigator, &bstr);
2904     ok(hres == S_OK, "get_platform failed: %08x\n", hres);
2905 #ifdef _WIN64
2906     ok(!strcmp_wa(bstr, "Win64"), "unexpected platform %s\n", wine_dbgstr_w(bstr));
2907 #else
2908     ok(!strcmp_wa(bstr, "Win32"), "unexpected platform %s\n", wine_dbgstr_w(bstr));
2909 #endif
2910     SysFreeString(bstr);
2911
2912     bstr = NULL;
2913     hres = IOmNavigator_get_appVersion(navigator, &bstr);
2914     ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
2915     ok(!memcmp(bstr, v40, sizeof(v40)), "appVersion is %s\n", wine_dbgstr_w(bstr));
2916     SysFreeString(bstr);
2917
2918     hres = IOmNavigator_toString(navigator, NULL);
2919     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
2920
2921     bstr = NULL;
2922     hres = IOmNavigator_toString(navigator, &bstr);
2923     ok(hres == S_OK, "toString failed: %08x\n", hres);
2924     ok(!strcmp_wa(bstr, "[object]"), "toString returned %s\n", wine_dbgstr_w(bstr));
2925     SysFreeString(bstr);
2926
2927     size = sizeof(buf);
2928     hres = ObtainUserAgentString(0, buf, &size);
2929     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
2930
2931     bstr = NULL;
2932     hres = IOmNavigator_get_userAgent(navigator, &bstr);
2933     ok(hres == S_OK, "get_userAgent failed: %08x\n", hres);
2934     ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf);
2935     SysFreeString(bstr);
2936
2937     ref = IOmNavigator_Release(navigator);
2938     ok(!ref, "navigator should be destroyed here\n");
2939 }
2940
2941 static void test_current_style(IHTMLCurrentStyle *current_style)
2942 {
2943     BSTR str;
2944     HRESULT hres;
2945     VARIANT v;
2946
2947     test_disp((IUnknown*)current_style, &DIID_DispHTMLCurrentStyle, "[object]");
2948     test_ifaces((IUnknown*)current_style, cstyle_iids);
2949
2950     hres = IHTMLCurrentStyle_get_display(current_style, &str);
2951     ok(hres == S_OK, "get_display failed: %08x\n", hres);
2952     ok(!strcmp_wa(str, "block"), "get_display returned %s\n", wine_dbgstr_w(str));
2953     SysFreeString(str);
2954
2955     hres = IHTMLCurrentStyle_get_position(current_style, &str);
2956     ok(hres == S_OK, "get_position failed: %08x\n", hres);
2957     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
2958     SysFreeString(str);
2959
2960     hres = IHTMLCurrentStyle_get_fontFamily(current_style, &str);
2961     ok(hres == S_OK, "get_fontFamily failed: %08x\n", hres);
2962     SysFreeString(str);
2963
2964     hres = IHTMLCurrentStyle_get_fontStyle(current_style, &str);
2965     ok(hres == S_OK, "get_fontStyle failed: %08x\n", hres);
2966     ok(!strcmp_wa(str, "normal"), "get_fontStyle returned %s\n", wine_dbgstr_w(str));
2967     SysFreeString(str);
2968
2969     hres = IHTMLCurrentStyle_get_backgroundImage(current_style, &str);
2970     ok(hres == S_OK, "get_backgroundImage failed: %08x\n", hres);
2971     ok(!strcmp_wa(str, "none"), "get_backgroundImage returned %s\n", wine_dbgstr_w(str));
2972     SysFreeString(str);
2973
2974     hres = IHTMLCurrentStyle_get_fontVariant(current_style, &str);
2975     ok(hres == S_OK, "get_fontVariant failed: %08x\n", hres);
2976     ok(!strcmp_wa(str, "normal"), "get_fontVariant returned %s\n", wine_dbgstr_w(str));
2977     SysFreeString(str);
2978
2979     hres = IHTMLCurrentStyle_get_borderTopStyle(current_style, &str);
2980     ok(hres == S_OK, "get_borderTopStyle failed: %08x\n", hres);
2981     ok(!strcmp_wa(str, "none"), "get_borderTopStyle returned %s\n", wine_dbgstr_w(str));
2982     SysFreeString(str);
2983
2984     hres = IHTMLCurrentStyle_get_borderRightStyle(current_style, &str);
2985     ok(hres == S_OK, "get_borderRightStyle failed: %08x\n", hres);
2986     ok(!strcmp_wa(str, "none"), "get_borderRightStyle returned %s\n", wine_dbgstr_w(str));
2987     SysFreeString(str);
2988
2989     hres = IHTMLCurrentStyle_get_borderBottomStyle(current_style, &str);
2990     ok(hres == S_OK, "get_borderBottomStyle failed: %08x\n", hres);
2991     ok(!strcmp_wa(str, "none"), "get_borderBottomStyle returned %s\n", wine_dbgstr_w(str));
2992     SysFreeString(str);
2993
2994     hres = IHTMLCurrentStyle_get_borderLeftStyle(current_style, &str);
2995     ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres);
2996     ok(!strcmp_wa(str, "none"), "get_borderLeftStyle returned %s\n", wine_dbgstr_w(str));
2997     SysFreeString(str);
2998
2999     hres = IHTMLCurrentStyle_get_textAlign(current_style, &str);
3000     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
3001     ok(!strcmp_wa(str, "center"), "get_textAlign returned %s\n", wine_dbgstr_w(str));
3002     SysFreeString(str);
3003
3004     hres = IHTMLCurrentStyle_get_textDecoration(current_style, &str);
3005     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3006     ok(!strcmp_wa(str, "none"), "get_textDecoration returned %s\n", wine_dbgstr_w(str));
3007     SysFreeString(str);
3008
3009     hres = IHTMLCurrentStyle_get_cursor(current_style, &str);
3010     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3011     ok(!strcmp_wa(str, "default"), "get_cursor returned %s\n", wine_dbgstr_w(str));
3012     SysFreeString(str);
3013
3014     hres = IHTMLCurrentStyle_get_backgroundRepeat(current_style, &str);
3015     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
3016     ok(!strcmp_wa(str, "repeat"), "get_backgroundRepeat returned %s\n", wine_dbgstr_w(str));
3017     SysFreeString(str);
3018
3019     hres = IHTMLCurrentStyle_get_borderColor(current_style, &str);
3020     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
3021     SysFreeString(str);
3022
3023     hres = IHTMLCurrentStyle_get_borderStyle(current_style, &str);
3024     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
3025     SysFreeString(str);
3026
3027     hres = IHTMLCurrentStyle_get_visibility(current_style, &str);
3028     ok(hres == S_OK, "get_visibility failed: %08x\n", hres);
3029     SysFreeString(str);
3030
3031     hres = IHTMLCurrentStyle_get_overflow(current_style, &str);
3032     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
3033     SysFreeString(str);
3034
3035     hres = IHTMLCurrentStyle_get_borderWidth(current_style, &str);
3036     ok(hres == S_OK, "get_borderWidth failed: %08x\n", hres);
3037     SysFreeString(str);
3038
3039     hres = IHTMLCurrentStyle_get_margin(current_style, &str);
3040     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3041     SysFreeString(str);
3042
3043     hres = IHTMLCurrentStyle_get_fontWeight(current_style, &v);
3044     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3045     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
3046     ok( V_I4(&v) == 400, "expect 400 got (%d)\n", V_I4(&v));
3047     VariantClear(&v);
3048
3049     hres = IHTMLCurrentStyle_get_fontSize(current_style, &v);
3050     ok(hres == S_OK, "get_fontSize failed: %08x\n", hres);
3051     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3052     VariantClear(&v);
3053
3054     hres = IHTMLCurrentStyle_get_left(current_style, &v);
3055     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3056     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3057     VariantClear(&v);
3058
3059     hres = IHTMLCurrentStyle_get_top(current_style, &v);
3060     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3061     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3062     VariantClear(&v);
3063
3064     hres = IHTMLCurrentStyle_get_width(current_style, &v);
3065     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3066     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3067     VariantClear(&v);
3068
3069     hres = IHTMLCurrentStyle_get_height(current_style, &v);
3070     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3071     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3072     VariantClear(&v);
3073
3074     hres = IHTMLCurrentStyle_get_paddingLeft(current_style, &v);
3075     ok(hres == S_OK, "get_paddingLeft failed: %08x\n", hres);
3076     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3077     VariantClear(&v);
3078
3079     hres = IHTMLCurrentStyle_get_zIndex(current_style, &v);
3080     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
3081     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
3082     ok( V_I4(&v) == 1, "expect 1 got (%d)\n", V_I4(&v));
3083     VariantClear(&v);
3084
3085     hres = IHTMLCurrentStyle_get_verticalAlign(current_style, &v);
3086     ok(hres == S_OK, "get_verticalAlign failed: %08x\n", hres);
3087     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3088     ok(!strcmp_wa(V_BSTR(&v), "middle"), "get_verticalAlign returned %s\n", wine_dbgstr_w(V_BSTR(&v)));
3089     VariantClear(&v);
3090
3091     hres = IHTMLCurrentStyle_get_marginRight(current_style, &v);
3092     ok(hres == S_OK, "get_marginRight failed: %08x\n", hres);
3093     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3094     VariantClear(&v);
3095
3096     hres = IHTMLCurrentStyle_get_marginLeft(current_style, &v);
3097     ok(hres == S_OK, "get_marginLeft failed: %08x\n", hres);
3098     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3099     VariantClear(&v);
3100
3101     hres = IHTMLCurrentStyle_get_borderLeftWidth(current_style, &v);
3102     ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres);
3103     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3104     VariantClear(&v);
3105
3106     V_BSTR(&v) = NULL;
3107     hres = IHTMLCurrentStyle_get_borderRightWidth(current_style, &v);
3108     ok(hres == S_OK, "get_borderRightWidth failed: %08x\n", hres);
3109     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3110     VariantClear(&v);
3111
3112     hres = IHTMLCurrentStyle_get_borderBottomWidth(current_style, &v);
3113     ok(hres == S_OK, "get_borderBottomWidth failed: %08x\n", hres);
3114     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3115     VariantClear(&v);
3116
3117     hres = IHTMLCurrentStyle_get_borderTopWidth(current_style, &v);
3118     ok(hres == S_OK, "get_borderTopWidth failed: %08x\n", hres);
3119     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3120     VariantClear(&v);
3121
3122     hres = IHTMLCurrentStyle_get_color(current_style, &v);
3123     ok(hres == S_OK, "get_color failed: %08x\n", hres);
3124     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3125     VariantClear(&v);
3126
3127     hres = IHTMLCurrentStyle_get_backgroundColor(current_style, &v);
3128     ok(hres == S_OK, "get_backgroundColor failed: %08x\n", hres);
3129     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3130     VariantClear(&v);
3131
3132     hres = IHTMLCurrentStyle_get_borderLeftColor(current_style, &v);
3133     ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres);
3134     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3135     VariantClear(&v);
3136
3137     hres = IHTMLCurrentStyle_get_borderTopColor(current_style, &v);
3138     ok(hres == S_OK, "get_borderTopColor failed: %08x\n", hres);
3139     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3140     VariantClear(&v);
3141
3142     hres = IHTMLCurrentStyle_get_borderRightColor(current_style, &v);
3143     ok(hres == S_OK, "get_borderRightColor failed: %08x\n", hres);
3144     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3145     VariantClear(&v);
3146
3147     hres = IHTMLCurrentStyle_get_borderBottomColor(current_style, &v);
3148     ok(hres == S_OK, "get_borderBottomColor failed: %08x\n", hres);
3149     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3150     VariantClear(&v);
3151
3152     hres = IHTMLCurrentStyle_get_paddingTop(current_style, &v);
3153     ok(hres == S_OK, "get_paddingTop failed: %08x\n", hres);
3154     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3155     VariantClear(&v);
3156
3157     hres = IHTMLCurrentStyle_get_paddingRight(current_style, &v);
3158     ok(hres == S_OK, "get_paddingRight failed: %08x\n", hres);
3159     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3160     VariantClear(&v);
3161
3162     hres = IHTMLCurrentStyle_get_paddingBottom(current_style, &v);
3163     ok(hres == S_OK, "get_paddingRight failed: %08x\n", hres);
3164     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3165     VariantClear(&v);
3166
3167     hres = IHTMLCurrentStyle_get_letterSpacing(current_style, &v);
3168     ok(hres == S_OK, "get_letterSpacing failed: %08x\n", hres);
3169     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3170     VariantClear(&v);
3171
3172     hres = IHTMLCurrentStyle_get_marginTop(current_style, &v);
3173     ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
3174     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3175     VariantClear(&v);
3176
3177     hres = IHTMLCurrentStyle_get_marginBottom(current_style, &v);
3178     ok(hres == S_OK, "get_marginBottom failed: %08x\n", hres);
3179     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3180     VariantClear(&v);
3181
3182     hres = IHTMLCurrentStyle_get_right(current_style, &v);
3183     ok(hres == S_OK, "get_Right failed: %08x\n", hres);
3184     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3185     VariantClear(&v);
3186
3187     hres = IHTMLCurrentStyle_get_bottom(current_style, &v);
3188     ok(hres == S_OK, "get_bottom failed: %08x\n", hres);
3189     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3190     VariantClear(&v);
3191
3192     hres = IHTMLCurrentStyle_get_lineHeight(current_style, &v);
3193     ok(hres == S_OK, "get_lineHeight failed: %08x\n", hres);
3194     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3195     VariantClear(&v);
3196
3197     hres = IHTMLCurrentStyle_get_textIndent(current_style, &v);
3198     ok(hres == S_OK, "get_textIndent failed: %08x\n", hres);
3199     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3200     VariantClear(&v);
3201 }
3202
3203 static void test_style2(IHTMLStyle2 *style2)
3204 {
3205     BSTR str;
3206     HRESULT hres;
3207
3208     str = (void*)0xdeadbeef;
3209     hres = IHTMLStyle2_get_position(style2, &str);
3210     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3211     ok(!str, "str != NULL\n");
3212
3213     str = a2bstr("absolute");
3214     hres = IHTMLStyle2_put_position(style2, str);
3215     ok(hres == S_OK, "put_position failed: %08x\n", hres);
3216     SysFreeString(str);
3217
3218     str = NULL;
3219     hres = IHTMLStyle2_get_position(style2, &str);
3220     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3221     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
3222     SysFreeString(str);
3223 }
3224
3225 static void test_style3(IHTMLStyle3 *style3)
3226 {
3227     BSTR str;
3228     HRESULT hres;
3229
3230     str = (void*)0xdeadbeef;
3231     hres = IHTMLStyle3_get_wordWrap(style3, &str);
3232     ok(hres == S_OK, "get_wordWrap failed: %08x\n", hres);
3233     ok(!str, "str != NULL\n");
3234
3235     str = a2bstr("break-word");
3236     hres = IHTMLStyle3_put_wordWrap(style3, str);
3237     ok(hres == S_OK, "put_wordWrap failed: %08x\n", hres);
3238     SysFreeString(str);
3239
3240     str = NULL;
3241     hres = IHTMLStyle3_get_wordWrap(style3, &str);
3242     ok(hres == S_OK, "get_wordWrap failed: %08x\n", hres);
3243     ok(!strcmp_wa(str, "break-word"), "get_wordWrap returned %s\n", wine_dbgstr_w(str));
3244     SysFreeString(str);
3245 }
3246
3247 static void test_style4(IHTMLStyle4 *style4)
3248 {
3249     HRESULT hres;
3250     VARIANT v;
3251     VARIANT vdefault;
3252
3253     hres = IHTMLStyle4_get_minHeight(style4, &vdefault);
3254     ok(hres == S_OK, "get_minHeight failed: %08x\n", hres);
3255
3256     V_VT(&v) = VT_BSTR;
3257     V_BSTR(&v) = a2bstr("10px");
3258     hres = IHTMLStyle4_put_minHeight(style4, v);
3259     ok(hres == S_OK, "put_minHeight failed: %08x\n", hres);
3260     VariantClear(&v);
3261
3262     hres = IHTMLStyle4_get_minHeight(style4, &v);
3263     ok(hres == S_OK, "get_minHeight failed: %08x\n", hres);
3264     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3265     ok( !strcmp_wa(V_BSTR(&v), "10px"), "expect 10px got (%s)\n", wine_dbgstr_w(V_BSTR(&v)));
3266
3267     hres = IHTMLStyle4_put_minHeight(style4, vdefault);
3268     ok(hres == S_OK, "put_minHeight failed: %08x\n", hres);
3269     VariantClear(&vdefault);
3270 }
3271
3272 static void test_default_style(IHTMLStyle *style)
3273 {
3274     IHTMLStyle2 *style2;
3275     IHTMLStyle3 *style3;
3276     IHTMLStyle4 *style4;
3277     VARIANT_BOOL b;
3278     VARIANT v;
3279     BSTR str;
3280     HRESULT hres;
3281     float f;
3282     BSTR sOverflowDefault;
3283     BSTR sDefault;
3284     VARIANT vDefault;
3285
3286     test_disp((IUnknown*)style, &DIID_DispHTMLStyle, "[object]");
3287     test_ifaces((IUnknown*)style, style_iids);
3288
3289     test_style_csstext(style, NULL);
3290
3291     hres = IHTMLStyle_get_position(style, &str);
3292     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3293     ok(!str, "str=%s\n", wine_dbgstr_w(str));
3294
3295     V_VT(&v) = VT_NULL;
3296     hres = IHTMLStyle_get_marginRight(style, &v);
3297     ok(hres == S_OK, "get_marginRight failed: %08x\n", hres);
3298     ok(V_VT(&v) == VT_BSTR, "V_VT(marginRight) = %d\n", V_VT(&v));
3299     ok(!V_BSTR(&v), "V_BSTR(marginRight) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3300
3301     V_VT(&v) = VT_NULL;
3302     hres = IHTMLStyle_get_marginLeft(style, &v);
3303     ok(hres == S_OK, "get_marginLeft failed: %08x\n", hres);
3304     ok(V_VT(&v) == VT_BSTR, "V_VT(marginLeft) = %d\n", V_VT(&v));
3305     ok(!V_BSTR(&v), "V_BSTR(marginLeft) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3306
3307     str = (void*)0xdeadbeef;
3308     hres = IHTMLStyle_get_fontFamily(style, &str);
3309     ok(hres == S_OK, "get_fontFamily failed: %08x\n", hres);
3310     ok(!str, "fontFamily = %s\n", wine_dbgstr_w(str));
3311
3312     str = (void*)0xdeadbeef;
3313     hres = IHTMLStyle_get_fontWeight(style, &str);
3314     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3315     ok(!str, "fontWeight = %s\n", wine_dbgstr_w(str));
3316
3317     hres = IHTMLStyle_get_fontWeight(style, &sDefault);
3318     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3319
3320     str = a2bstr("test");
3321     hres = IHTMLStyle_put_fontWeight(style, str);
3322     ok(hres == E_INVALIDARG, "put_fontWeight failed: %08x\n", hres);
3323     SysFreeString(str);
3324
3325     str = a2bstr("bold");
3326     hres = IHTMLStyle_put_fontWeight(style, str);
3327     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3328     SysFreeString(str);
3329
3330     str = a2bstr("bolder");
3331     hres = IHTMLStyle_put_fontWeight(style, str);
3332     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3333     SysFreeString(str);
3334
3335     str = a2bstr("lighter");
3336     hres = IHTMLStyle_put_fontWeight(style, str);
3337     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3338     SysFreeString(str);
3339
3340     str = a2bstr("100");
3341     hres = IHTMLStyle_put_fontWeight(style, str);
3342     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3343     SysFreeString(str);
3344
3345     str = a2bstr("200");
3346     hres = IHTMLStyle_put_fontWeight(style, str);
3347     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3348     SysFreeString(str);
3349
3350     str = a2bstr("300");
3351     hres = IHTMLStyle_put_fontWeight(style, str);
3352     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3353     SysFreeString(str);
3354
3355     str = a2bstr("400");
3356     hres = IHTMLStyle_put_fontWeight(style, str);
3357     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3358     SysFreeString(str);
3359
3360     str = a2bstr("500");
3361     hres = IHTMLStyle_put_fontWeight(style, str);
3362     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3363     SysFreeString(str);
3364
3365     str = a2bstr("600");
3366     hres = IHTMLStyle_put_fontWeight(style, str);
3367     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3368     SysFreeString(str);
3369
3370     str = a2bstr("700");
3371     hres = IHTMLStyle_put_fontWeight(style, str);
3372     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3373     SysFreeString(str);
3374
3375     str = a2bstr("800");
3376     hres = IHTMLStyle_put_fontWeight(style, str);
3377     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3378     SysFreeString(str);
3379
3380     str = a2bstr("900");
3381     hres = IHTMLStyle_put_fontWeight(style, str);
3382     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3383     SysFreeString(str);
3384
3385     hres = IHTMLStyle_get_fontWeight(style, &str);
3386     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3387     ok(!strcmp_wa(str, "900"), "str != style900\n");
3388     SysFreeString(str);
3389
3390     hres = IHTMLStyle_put_fontWeight(style, sDefault);
3391     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3392     SysFreeString(sDefault);
3393
3394     /* font Variant */
3395     hres = IHTMLStyle_get_fontVariant(style, NULL);
3396     ok(hres == E_INVALIDARG, "get_fontVariant failed: %08x\n", hres);
3397
3398     hres = IHTMLStyle_get_fontVariant(style, &sDefault);
3399     ok(hres == S_OK, "get_fontVariant failed: %08x\n", hres);
3400
3401     str = a2bstr("test");
3402     hres = IHTMLStyle_put_fontVariant(style, str);
3403     ok(hres == E_INVALIDARG, "fontVariant failed: %08x\n", hres);
3404     SysFreeString(str);
3405
3406     str = a2bstr("small-caps");
3407     hres = IHTMLStyle_put_fontVariant(style, str);
3408     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3409     SysFreeString(str);
3410
3411     str = a2bstr("normal");
3412     hres = IHTMLStyle_put_fontVariant(style, str);
3413     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3414     SysFreeString(str);
3415
3416     hres = IHTMLStyle_put_fontVariant(style, sDefault);
3417     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3418     SysFreeString(sDefault);
3419
3420     str = (void*)0xdeadbeef;
3421     hres = IHTMLStyle_get_display(style, &str);
3422     ok(hres == S_OK, "get_display failed: %08x\n", hres);
3423     ok(!str, "display = %s\n", wine_dbgstr_w(str));
3424
3425     str = (void*)0xdeadbeef;
3426     hres = IHTMLStyle_get_visibility(style, &str);
3427     ok(hres == S_OK, "get_visibility failed: %08x\n", hres);
3428     ok(!str, "visibility = %s\n", wine_dbgstr_w(str));
3429
3430     V_VT(&v) = VT_NULL;
3431     hres = IHTMLStyle_get_fontSize(style, &v);
3432     ok(hres == S_OK, "get_fontSize failed: %08x\n", hres);
3433     ok(V_VT(&v) == VT_BSTR, "V_VT(fontSize) = %d\n", V_VT(&v));
3434     ok(!V_BSTR(&v), "V_BSTR(fontSize) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3435
3436     V_VT(&v) = VT_NULL;
3437     hres = IHTMLStyle_get_color(style, &v);
3438     ok(hres == S_OK, "get_color failed: %08x\n", hres);
3439     ok(V_VT(&v) == VT_BSTR, "V_VT(color) = %d\n", V_VT(&v));
3440     ok(!V_BSTR(&v), "V_BSTR(color) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3441
3442     b = 0xfefe;
3443     hres = IHTMLStyle_get_textDecorationUnderline(style, &b);
3444     ok(hres == S_OK, "get_textDecorationUnderline failed: %08x\n", hres);
3445     ok(b == VARIANT_FALSE, "textDecorationUnderline = %x\n", b);
3446
3447     hres = IHTMLStyle_put_textDecorationUnderline(style, VARIANT_TRUE);
3448     ok(hres == S_OK, "put_textDecorationUnderline failed: %08x\n", hres);
3449     ok(b == VARIANT_FALSE, "textDecorationUnderline = %x\n", b);
3450
3451     hres = IHTMLStyle_get_textDecorationUnderline(style, &b);
3452     ok(hres == S_OK, "get_textDecorationUnderline failed: %08x\n", hres);
3453     ok(b == VARIANT_TRUE, "textDecorationUnderline = %x\n", b);
3454
3455     hres = IHTMLStyle_put_textDecorationUnderline(style, VARIANT_FALSE);
3456     ok(hres == S_OK, "put_textDecorationUnderline failed: %08x\n", hres);
3457
3458     b = 0xfefe;
3459     hres = IHTMLStyle_get_textDecorationLineThrough(style, &b);
3460     ok(hres == S_OK, "get_textDecorationLineThrough failed: %08x\n", hres);
3461     ok(b == VARIANT_FALSE, "textDecorationLineThrough = %x\n", b);
3462
3463     hres = IHTMLStyle_put_textDecorationLineThrough(style, VARIANT_TRUE);
3464     ok(hres == S_OK, "put_textDecorationLineThrough failed: %08x\n", hres);
3465     ok(b == VARIANT_FALSE, "textDecorationLineThrough = %x\n", b);
3466
3467     hres = IHTMLStyle_get_textDecorationLineThrough(style, &b);
3468     ok(hres == S_OK, "get_textDecorationLineThrough failed: %08x\n", hres);
3469     ok(b == VARIANT_TRUE, "textDecorationLineThrough = %x\n", b);
3470
3471     hres = IHTMLStyle_put_textDecorationLineThrough(style, VARIANT_FALSE);
3472     ok(hres == S_OK, "put_textDecorationLineThrough failed: %08x\n", hres);
3473
3474     b = 0xfefe;
3475     hres = IHTMLStyle_get_textDecorationNone(style, &b);
3476     ok(hres == S_OK, "get_textDecorationNone failed: %08x\n", hres);
3477     ok(b == VARIANT_FALSE, "textDecorationNone = %x\n", b);
3478
3479     hres = IHTMLStyle_put_textDecorationNone(style, VARIANT_TRUE);
3480     ok(hres == S_OK, "put_textDecorationNone failed: %08x\n", hres);
3481     ok(b == VARIANT_FALSE, "textDecorationNone = %x\n", b);
3482
3483     hres = IHTMLStyle_get_textDecorationNone(style, &b);
3484     ok(hres == S_OK, "get_textDecorationNone failed: %08x\n", hres);
3485     ok(b == VARIANT_TRUE, "textDecorationNone = %x\n", b);
3486
3487     hres = IHTMLStyle_put_textDecorationNone(style, VARIANT_FALSE);
3488     ok(hres == S_OK, "put_textDecorationNone failed: %08x\n", hres);
3489
3490     b = 0xfefe;
3491     hres = IHTMLStyle_get_textDecorationOverline(style, &b);
3492     ok(hres == S_OK, "get_textDecorationOverline failed: %08x\n", hres);
3493     ok(b == VARIANT_FALSE, "textDecorationOverline = %x\n", b);
3494
3495     hres = IHTMLStyle_put_textDecorationOverline(style, VARIANT_TRUE);
3496     ok(hres == S_OK, "put_textDecorationOverline failed: %08x\n", hres);
3497     ok(b == VARIANT_FALSE, "textDecorationOverline = %x\n", b);
3498
3499     hres = IHTMLStyle_get_textDecorationOverline(style, &b);
3500     ok(hres == S_OK, "get_textDecorationOverline failed: %08x\n", hres);
3501     ok(b == VARIANT_TRUE, "textDecorationOverline = %x\n", b);
3502
3503     hres = IHTMLStyle_put_textDecorationOverline(style, VARIANT_FALSE);
3504     ok(hres == S_OK, "put_textDecorationOverline failed: %08x\n", hres);
3505
3506     b = 0xfefe;
3507     hres = IHTMLStyle_get_textDecorationBlink(style, &b);
3508     ok(hres == S_OK, "get_textDecorationBlink failed: %08x\n", hres);
3509     ok(b == VARIANT_FALSE, "textDecorationBlink = %x\n", b);
3510
3511     hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_TRUE);
3512     ok(hres == S_OK, "put_textDecorationBlink failed: %08x\n", hres);
3513     ok(b == VARIANT_FALSE, "textDecorationBlink = %x\n", b);
3514
3515     hres = IHTMLStyle_get_textDecorationBlink(style, &b);
3516     ok(hres == S_OK, "get_textDecorationBlink failed: %08x\n", hres);
3517     ok(b == VARIANT_TRUE, "textDecorationBlink = %x\n", b);
3518
3519     hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_FALSE);
3520     ok(hres == S_OK, "textDecorationBlink failed: %08x\n", hres);
3521
3522     hres = IHTMLStyle_get_textDecoration(style, &sDefault);
3523     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3524
3525     str = a2bstr("invalid");
3526     hres = IHTMLStyle_put_textDecoration(style, str);
3527     ok(hres == E_INVALIDARG, "put_textDecoration failed: %08x\n", hres);
3528     SysFreeString(str);
3529
3530     str = a2bstr("none");
3531     hres = IHTMLStyle_put_textDecoration(style, str);
3532     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3533     SysFreeString(str);
3534
3535     str = a2bstr("underline");
3536     hres = IHTMLStyle_put_textDecoration(style, str);
3537     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3538     SysFreeString(str);
3539
3540     str = a2bstr("overline");
3541     hres = IHTMLStyle_put_textDecoration(style, str);
3542     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3543     SysFreeString(str);
3544
3545     str = a2bstr("line-through");
3546     hres = IHTMLStyle_put_textDecoration(style, str);
3547     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3548     SysFreeString(str);
3549
3550     str = a2bstr("blink");
3551     hres = IHTMLStyle_put_textDecoration(style, str);
3552     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3553     SysFreeString(str);
3554
3555     hres = IHTMLStyle_get_textDecoration(style, &str);
3556     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3557     ok(!strcmp_wa(str, "blink"), "str != blink\n");
3558     SysFreeString(str);
3559
3560     hres = IHTMLStyle_put_textDecoration(style, sDefault);
3561     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3562     SysFreeString(sDefault);
3563
3564     hres = IHTMLStyle_get_posWidth(style, NULL);
3565     ok(hres == E_POINTER, "get_posWidth failed: %08x\n", hres);
3566
3567     hres = IHTMLStyle_get_posWidth(style, &f);
3568     ok(hres == S_OK, "get_posWidth failed: %08x\n", hres);
3569     ok(f == 0.0f, "f = %f\n", f);
3570
3571     V_VT(&v) = VT_EMPTY;
3572     hres = IHTMLStyle_get_width(style, &v);
3573     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3574     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3575     ok(!V_BSTR(&v), "V_BSTR(v)=%p\n", V_BSTR(&v));
3576
3577     hres = IHTMLStyle_put_posWidth(style, 2.2);
3578     ok(hres == S_OK, "put_posWidth failed: %08x\n", hres);
3579
3580     hres = IHTMLStyle_get_posWidth(style, &f);
3581     ok(hres == S_OK, "get_posWidth failed: %08x\n", hres);
3582     ok(f == 2.0f ||
3583        f == 2.2f, /* IE8 */
3584        "f = %f\n", f);
3585
3586     V_VT(&v) = VT_BSTR;
3587     V_BSTR(&v) = a2bstr("auto");
3588     hres = IHTMLStyle_put_width(style, v);
3589     ok(hres == S_OK, "put_width failed: %08x\n", hres);
3590     VariantClear(&v);
3591
3592     V_VT(&v) = VT_EMPTY;
3593     hres = IHTMLStyle_get_width(style, &v);
3594     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3595     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3596     ok(!strcmp_wa(V_BSTR(&v), "auto"), "V_BSTR(v)=%s\n", wine_dbgstr_w(V_BSTR(&v)));
3597     VariantClear(&v);
3598
3599     /* margin tests */
3600     str = (void*)0xdeadbeef;
3601     hres = IHTMLStyle_get_margin(style, &str);
3602     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3603     ok(!str, "margin = %s\n", wine_dbgstr_w(str));
3604
3605     str = a2bstr("1");
3606     hres = IHTMLStyle_put_margin(style, str);
3607     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
3608     SysFreeString(str);
3609
3610     hres = IHTMLStyle_get_margin(style, &str);
3611     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3612     ok(!strcmp_wa(str, "1px"), "margin = %s\n", wine_dbgstr_w(str));
3613
3614     hres = IHTMLStyle_put_margin(style, NULL);
3615     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
3616
3617     str = NULL;
3618     hres = IHTMLStyle_get_border(style, &str);
3619     ok(hres == S_OK, "get_border failed: %08x\n", hres);
3620     ok(!str || !*str, "str is not empty\n");
3621     SysFreeString(str);
3622
3623     str = a2bstr("1px");
3624     hres = IHTMLStyle_put_border(style, str);
3625     ok(hres == S_OK, "put_border failed: %08x\n", hres);
3626     SysFreeString(str);
3627
3628     V_VT(&v) = VT_EMPTY;
3629     hres = IHTMLStyle_get_left(style, &v);
3630     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3631     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3632     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3633     VariantClear(&v);
3634
3635     /* Test posLeft */
3636     hres = IHTMLStyle_get_posLeft(style, NULL);
3637     ok(hres == E_POINTER, "get_posLeft failed: %08x\n", hres);
3638
3639     f = 1.0f;
3640     hres = IHTMLStyle_get_posLeft(style, &f);
3641     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3642     ok(f == 0.0, "expected 0.0 got %f\n", f);
3643
3644     hres = IHTMLStyle_put_posLeft(style, 4.9f);
3645     ok(hres == S_OK, "put_posLeft failed: %08x\n", hres);
3646
3647     hres = IHTMLStyle_get_posLeft(style, &f);
3648     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3649     ok(f == 4.0 ||
3650        f == 4.9f, /* IE8 */
3651        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3652
3653     /* Ensure left is updated correctly. */
3654     V_VT(&v) = VT_EMPTY;
3655     hres = IHTMLStyle_get_left(style, &v);
3656     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3657     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3658     ok(!strcmp_wa(V_BSTR(&v), "4px") ||
3659        !strcmp_wa(V_BSTR(&v), "4.9px"), /* IE8 */
3660        "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3661     VariantClear(&v);
3662
3663     /* Test left */
3664     V_VT(&v) = VT_BSTR;
3665     V_BSTR(&v) = a2bstr("3px");
3666     hres = IHTMLStyle_put_left(style, v);
3667     ok(hres == S_OK, "put_left failed: %08x\n", hres);
3668     VariantClear(&v);
3669
3670     hres = IHTMLStyle_get_posLeft(style, &f);
3671     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3672     ok(f == 3.0, "expected 3.0 got %f\n", f);
3673
3674     V_VT(&v) = VT_EMPTY;
3675     hres = IHTMLStyle_get_left(style, &v);
3676     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3677     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3678     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3679     VariantClear(&v);
3680
3681     V_VT(&v) = VT_NULL;
3682     hres = IHTMLStyle_put_left(style, v);
3683     ok(hres == S_OK, "put_left failed: %08x\n", hres);
3684
3685     V_VT(&v) = VT_EMPTY;
3686     hres = IHTMLStyle_get_left(style, &v);
3687     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3688     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3689     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3690     VariantClear(&v);
3691
3692     V_VT(&v) = VT_EMPTY;
3693     hres = IHTMLStyle_get_top(style, &v);
3694     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3695     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3696     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3697     VariantClear(&v);
3698
3699     /* Test posTop */
3700     hres = IHTMLStyle_get_posTop(style, NULL);
3701     ok(hres == E_POINTER, "get_posTop failed: %08x\n", hres);
3702
3703     f = 1.0f;
3704     hres = IHTMLStyle_get_posTop(style, &f);
3705     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3706     ok(f == 0.0, "expected 0.0 got %f\n", f);
3707
3708     hres = IHTMLStyle_put_posTop(style, 4.9f);
3709     ok(hres == S_OK, "put_posTop failed: %08x\n", hres);
3710
3711     hres = IHTMLStyle_get_posTop(style, &f);
3712     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3713     ok(f == 4.0 ||
3714        f == 4.9f, /* IE8 */
3715        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3716
3717     V_VT(&v) = VT_BSTR;
3718     V_BSTR(&v) = a2bstr("3px");
3719     hres = IHTMLStyle_put_top(style, v);
3720     ok(hres == S_OK, "put_top failed: %08x\n", hres);
3721     VariantClear(&v);
3722
3723     V_VT(&v) = VT_EMPTY;
3724     hres = IHTMLStyle_get_top(style, &v);
3725     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3726     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3727     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3728     VariantClear(&v);
3729
3730     hres = IHTMLStyle_get_posTop(style, &f);
3731     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3732     ok(f == 3.0, "expected 3.0 got %f\n", f);
3733
3734     V_VT(&v) = VT_NULL;
3735     hres = IHTMLStyle_put_top(style, v);
3736     ok(hres == S_OK, "put_top failed: %08x\n", hres);
3737
3738     V_VT(&v) = VT_EMPTY;
3739     hres = IHTMLStyle_get_top(style, &v);
3740     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3741     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3742     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3743     VariantClear(&v);
3744
3745     /* Test posHeight */
3746     hres = IHTMLStyle_get_posHeight(style, NULL);
3747     ok(hres == E_POINTER, "get_posHeight failed: %08x\n", hres);
3748
3749     V_VT(&v) = VT_EMPTY;
3750     hres = IHTMLStyle_get_height(style, &v);
3751     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3752     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3753     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3754     VariantClear(&v);
3755
3756     f = 1.0f;
3757     hres = IHTMLStyle_get_posHeight(style, &f);
3758     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
3759     ok(f == 0.0, "expected 0.0 got %f\n", f);
3760
3761     hres = IHTMLStyle_put_posHeight(style, 4.9f);
3762     ok(hres == S_OK, "put_posHeight failed: %08x\n", hres);
3763
3764     hres = IHTMLStyle_get_posHeight(style, &f);
3765     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
3766     ok(f == 4.0 ||
3767        f == 4.9f, /* IE8 */
3768        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3769
3770     V_VT(&v) = VT_BSTR;
3771     V_BSTR(&v) = a2bstr("64px");
3772     hres = IHTMLStyle_put_height(style, v);
3773     ok(hres == S_OK, "put_height failed: %08x\n", hres);
3774     VariantClear(&v);
3775
3776     V_VT(&v) = VT_EMPTY;
3777     hres = IHTMLStyle_get_height(style, &v);
3778     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3779     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3780     ok(!strcmp_wa(V_BSTR(&v), "64px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3781     VariantClear(&v);
3782
3783     hres = IHTMLStyle_get_posHeight(style, &f);
3784     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
3785     ok(f == 64.0, "expected 64.0 got %f\n", f);
3786
3787     str = (void*)0xdeadbeef;
3788     hres = IHTMLStyle_get_cursor(style, &str);
3789     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3790     ok(!str, "get_cursor != NULL\n");
3791     SysFreeString(str);
3792
3793     str = a2bstr("default");
3794     hres = IHTMLStyle_put_cursor(style, str);
3795     ok(hres == S_OK, "put_cursor failed: %08x\n", hres);
3796     SysFreeString(str);
3797
3798     str = NULL;
3799     hres = IHTMLStyle_get_cursor(style, &str);
3800     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3801     ok(!strcmp_wa(str, "default"), "get_cursor returned %s\n", wine_dbgstr_w(str));
3802     SysFreeString(str);
3803
3804     V_VT(&v) = VT_EMPTY;
3805     hres = IHTMLStyle_get_verticalAlign(style, &v);
3806     ok(hres == S_OK, "get_vertivalAlign failed: %08x\n", hres);
3807     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3808     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3809     VariantClear(&v);
3810
3811     V_VT(&v) = VT_BSTR;
3812     V_BSTR(&v) = a2bstr("middle");
3813     hres = IHTMLStyle_put_verticalAlign(style, v);
3814     ok(hres == S_OK, "put_vertivalAlign failed: %08x\n", hres);
3815     VariantClear(&v);
3816
3817     V_VT(&v) = VT_EMPTY;
3818     hres = IHTMLStyle_get_verticalAlign(style, &v);
3819     ok(hres == S_OK, "get_verticalAlign failed: %08x\n", hres);
3820     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3821     ok(!strcmp_wa(V_BSTR(&v), "middle"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3822     VariantClear(&v);
3823
3824     str = (void*)0xdeadbeef;
3825     hres = IHTMLStyle_get_textAlign(style, &str);
3826     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
3827     ok(!str, "textAlign != NULL\n");
3828
3829     str = a2bstr("center");
3830     hres = IHTMLStyle_put_textAlign(style, str);
3831     ok(hres == S_OK, "put_textAlign failed: %08x\n", hres);
3832     SysFreeString(str);
3833
3834     str = NULL;
3835     hres = IHTMLStyle_get_textAlign(style, &str);
3836     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
3837     ok(!strcmp_wa(str, "center"), "textAlign = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3838     SysFreeString(str);
3839
3840     str = (void*)0xdeadbeef;
3841     hres = IHTMLStyle_get_filter(style, &str);
3842     ok(hres == S_OK, "get_filter failed: %08x\n", hres);
3843     ok(!str, "filter != NULL\n");
3844
3845     str = a2bstr("alpha(opacity=100)");
3846     hres = IHTMLStyle_put_filter(style, str);
3847     ok(hres == S_OK, "put_filter failed: %08x\n", hres);
3848     SysFreeString(str);
3849
3850     V_VT(&v) = VT_EMPTY;
3851     hres = IHTMLStyle_get_zIndex(style, &v);
3852     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
3853     ok(V_VT(&v) == VT_I4, "V_VT(v)=%d\n", V_VT(&v));
3854     ok(!V_I4(&v), "V_I4(v) != 0\n");
3855     VariantClear(&v);
3856
3857     V_VT(&v) = VT_BSTR;
3858     V_BSTR(&v) = a2bstr("1");
3859     hres = IHTMLStyle_put_zIndex(style, v);
3860     ok(hres == S_OK, "put_zIndex failed: %08x\n", hres);
3861     VariantClear(&v);
3862
3863     V_VT(&v) = VT_EMPTY;
3864     hres = IHTMLStyle_get_zIndex(style, &v);
3865     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
3866     ok(V_VT(&v) == VT_I4, "V_VT(v)=%d\n", V_VT(&v));
3867     ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v));
3868     VariantClear(&v);
3869
3870     /* fontStyle */
3871     hres = IHTMLStyle_get_fontStyle(style, &sDefault);
3872     ok(hres == S_OK, "get_fontStyle failed: %08x\n", hres);
3873
3874     str = a2bstr("test");
3875     hres = IHTMLStyle_put_fontStyle(style, str);
3876     ok(hres == E_INVALIDARG, "put_fontStyle failed: %08x\n", hres);
3877     SysFreeString(str);
3878
3879     str = a2bstr("italic");
3880     hres = IHTMLStyle_put_fontStyle(style, str);
3881     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
3882     SysFreeString(str);
3883
3884     str = a2bstr("oblique");
3885     hres = IHTMLStyle_put_fontStyle(style, str);
3886     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
3887     SysFreeString(str);
3888
3889     str = a2bstr("normal");
3890     hres = IHTMLStyle_put_fontStyle(style, str);
3891     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
3892     SysFreeString(str);
3893
3894     hres = IHTMLStyle_put_fontStyle(style, sDefault);
3895     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
3896     SysFreeString(sDefault);
3897
3898     /* overflow */
3899     hres = IHTMLStyle_get_overflow(style, NULL);
3900     ok(hres == E_INVALIDARG, "get_overflow failed: %08x\n", hres);
3901
3902     hres = IHTMLStyle_get_overflow(style, &sOverflowDefault);
3903     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
3904
3905     str = a2bstr("test");
3906     hres = IHTMLStyle_put_overflow(style, str);
3907     ok(hres == E_INVALIDARG, "put_overflow failed: %08x\n", hres);
3908     SysFreeString(str);
3909
3910     str = a2bstr("visible");
3911     hres = IHTMLStyle_put_overflow(style, str);
3912     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
3913     SysFreeString(str);
3914
3915     str = a2bstr("scroll");
3916     hres = IHTMLStyle_put_overflow(style, str);
3917     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
3918     SysFreeString(str);
3919
3920     str = a2bstr("hidden");
3921     hres = IHTMLStyle_put_overflow(style, str);
3922     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
3923     SysFreeString(str);
3924
3925     str = a2bstr("auto");
3926     hres = IHTMLStyle_put_overflow(style, str);
3927     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
3928     SysFreeString(str);
3929
3930     hres = IHTMLStyle_get_overflow(style, &str);
3931     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
3932     ok(!strcmp_wa(str, "auto"), "str=%s\n", wine_dbgstr_w(str));
3933     SysFreeString(str);
3934
3935     str = a2bstr("");
3936     hres = IHTMLStyle_put_overflow(style, str);
3937     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
3938     SysFreeString(str);
3939
3940     hres = IHTMLStyle_get_overflow(style, &str);
3941     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
3942     ok(!str, "str=%s\n", wine_dbgstr_w(str));
3943     SysFreeString(str);
3944
3945     /* restore overflow default */
3946     hres = IHTMLStyle_put_overflow(style, sOverflowDefault);
3947     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
3948     SysFreeString(sOverflowDefault);
3949
3950     /* Attribute Tests*/
3951     hres = IHTMLStyle_getAttribute(style, NULL, 1, &v);
3952     ok(hres == E_INVALIDARG, "getAttribute failed: %08x\n", hres);
3953
3954     str = a2bstr("position");
3955     hres = IHTMLStyle_getAttribute(style, str, 1, NULL);
3956     ok(hres == E_INVALIDARG, "getAttribute failed: %08x\n", hres);
3957
3958     hres = IHTMLStyle_getAttribute(style, str, 1, &v);
3959     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
3960     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
3961     VariantClear(&v);
3962
3963     hres = IHTMLStyle_setAttribute(style, NULL, v, 1);
3964     ok(hres == E_INVALIDARG, "setAttribute failed: %08x\n", hres);
3965
3966     V_VT(&v) = VT_BSTR;
3967     V_BSTR(&v) = a2bstr("absolute");
3968     hres = IHTMLStyle_setAttribute(style, str, v, 1);
3969     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
3970     VariantClear(&v);
3971
3972     hres = IHTMLStyle_getAttribute(style, str, 1, &v);
3973     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
3974     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
3975     ok(!strcmp_wa(V_BSTR(&v), "absolute"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
3976     VariantClear(&v);
3977
3978     V_VT(&v) = VT_BSTR;
3979     V_BSTR(&v) = NULL;
3980     hres = IHTMLStyle_setAttribute(style, str, v, 1);
3981     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
3982     VariantClear(&v);
3983
3984     SysFreeString(str);
3985
3986     str = a2bstr("borderLeftStyle");
3987     test_border_styles(style, str);
3988     SysFreeString(str);
3989
3990     str = a2bstr("borderbottomstyle");
3991     test_border_styles(style, str);
3992     SysFreeString(str);
3993
3994     str = a2bstr("borderrightstyle");
3995     test_border_styles(style, str);
3996     SysFreeString(str);
3997
3998     str = a2bstr("bordertopstyle");
3999     test_border_styles(style, str);
4000     SysFreeString(str);
4001
4002     hres = IHTMLStyle_get_borderStyle(style, &sDefault);
4003     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
4004
4005     str = a2bstr("none dotted dashed solid");
4006     hres = IHTMLStyle_put_borderStyle(style, str);
4007     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4008     SysFreeString(str);
4009
4010     str = a2bstr("none dotted dashed solid");
4011     hres = IHTMLStyle_get_borderStyle(style, &str);
4012     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
4013     ok(!strcmp_wa(str, "none dotted dashed solid"),
4014         "expected (none dotted dashed solid) = (%s)\n", wine_dbgstr_w(V_BSTR(&v)));
4015     SysFreeString(str);
4016
4017     str = a2bstr("double groove ridge inset");
4018     hres = IHTMLStyle_put_borderStyle(style, str);
4019     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4020     SysFreeString(str);
4021
4022     str = a2bstr("window-inset outset ridge inset");
4023     hres = IHTMLStyle_put_borderStyle(style, str);
4024     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4025     SysFreeString(str);
4026
4027     str = a2bstr("window-inset");
4028     hres = IHTMLStyle_put_borderStyle(style, str);
4029     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4030     SysFreeString(str);
4031
4032     str = a2bstr("none none none none none");
4033     hres = IHTMLStyle_put_borderStyle(style, str);
4034     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4035     SysFreeString(str);
4036
4037     str = a2bstr("invalid none none none");
4038     hres = IHTMLStyle_put_borderStyle(style, str);
4039     ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres);
4040     SysFreeString(str);
4041
4042     str = a2bstr("none invalid none none");
4043     hres = IHTMLStyle_put_borderStyle(style, str);
4044     ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres);
4045     SysFreeString(str);
4046
4047     hres = IHTMLStyle_put_borderStyle(style, sDefault);
4048     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4049     SysFreeString(sDefault);
4050
4051     /* backgoundColor */
4052     hres = IHTMLStyle_get_backgroundColor(style, &v);
4053     ok(hres == S_OK, "get_backgroundColor: %08x\n", hres);
4054     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4055     ok(!V_BSTR(&v), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4056     VariantClear(&v);
4057
4058     /* PaddingLeft */
4059     hres = IHTMLStyle_get_paddingLeft(style, &vDefault);
4060     ok(hres == S_OK, "get_paddingLeft: %08x\n", hres);
4061
4062     V_VT(&v) = VT_BSTR;
4063     V_BSTR(&v) = a2bstr("10");
4064     hres = IHTMLStyle_put_paddingLeft(style, v);
4065     ok(hres == S_OK, "put_paddingLeft: %08x\n", hres);
4066     VariantClear(&v);
4067
4068     hres = IHTMLStyle_get_paddingLeft(style, &v);
4069     ok(hres == S_OK, "get_paddingLeft: %08x\n", hres);
4070     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expecte 10 = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4071
4072     hres = IHTMLStyle_put_paddingLeft(style, vDefault);
4073     ok(hres == S_OK, "put_paddingLeft: %08x\n", hres);
4074
4075     /* BackgroundRepeat */
4076     hres = IHTMLStyle_get_backgroundRepeat(style, &sDefault);
4077     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
4078
4079     str = a2bstr("invalid");
4080     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4081     ok(hres == E_INVALIDARG, "put_backgroundRepeat failed: %08x\n", hres);
4082     SysFreeString(str);
4083
4084     str = a2bstr("repeat");
4085     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4086     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4087     SysFreeString(str);
4088
4089     str = a2bstr("no-repeat");
4090     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4091     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4092     SysFreeString(str);
4093
4094     str = a2bstr("repeat-x");
4095     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4096     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4097     SysFreeString(str);
4098
4099     str = a2bstr("repeat-y");
4100     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4101     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4102     SysFreeString(str);
4103
4104     hres = IHTMLStyle_get_backgroundRepeat(style, &str);
4105     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
4106     ok(!strcmp_wa(str, "repeat-y"), "str=%s\n", wine_dbgstr_w(str));
4107     SysFreeString(str);
4108
4109     hres = IHTMLStyle_put_backgroundRepeat(style, sDefault);
4110     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4111     SysFreeString(sDefault);
4112
4113     /* BorderColor */
4114     hres = IHTMLStyle_get_borderColor(style, &sDefault);
4115     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
4116
4117     str = a2bstr("red green red blue");
4118     hres = IHTMLStyle_put_borderColor(style, str);
4119     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
4120     SysFreeString(str);
4121
4122     hres = IHTMLStyle_get_borderColor(style, &str);
4123     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
4124     ok(!strcmp_wa(str, "red green red blue"), "str=%s\n", wine_dbgstr_w(str));
4125     SysFreeString(str);
4126
4127     hres = IHTMLStyle_put_borderColor(style, sDefault);
4128     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
4129     SysFreeString(sDefault);
4130
4131     /* BorderLeft */
4132     hres = IHTMLStyle_get_borderLeft(style, &sDefault);
4133     ok(hres == S_OK, "get_borderLeft failed: %08x\n", hres);
4134
4135     str = a2bstr("thick dotted red");
4136     hres = IHTMLStyle_put_borderLeft(style, str);
4137     ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres);
4138     SysFreeString(str);
4139
4140     /* IHTMLStyle_get_borderLeft appears to have a bug where
4141         it returns the first letter of the color.  So we check
4142         each style individually.
4143      */
4144     V_BSTR(&v) = NULL;
4145     hres = IHTMLStyle_get_borderLeftColor(style, &v);
4146     todo_wine ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres);
4147     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4148     VariantClear(&v);
4149
4150     V_BSTR(&v) = NULL;
4151     hres = IHTMLStyle_get_borderLeftWidth(style, &v);
4152     ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres);
4153     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4154     VariantClear(&v);
4155
4156     hres = IHTMLStyle_get_borderLeftStyle(style, &str);
4157     ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres);
4158     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4159     SysFreeString(str);
4160
4161     hres = IHTMLStyle_put_borderLeft(style, sDefault);
4162     ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres);
4163     SysFreeString(sDefault);
4164
4165     /* backgroundPositionX */
4166     hres = IHTMLStyle_get_backgroundPositionX(style, &vDefault);
4167     ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres);
4168
4169     V_VT(&v) = VT_BSTR;
4170     V_BSTR(&v) = a2bstr("10px");
4171     hres = IHTMLStyle_put_backgroundPositionX(style, v);
4172     ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres);
4173     VariantClear(&v);
4174
4175     hres = IHTMLStyle_get_backgroundPositionX(style, &v);
4176     ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres);
4177     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4178     VariantClear(&v);
4179
4180     hres = IHTMLStyle_put_backgroundPositionX(style, vDefault);
4181     ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres);
4182     VariantClear(&vDefault);
4183
4184     /* backgroundPositionY */
4185     hres = IHTMLStyle_get_backgroundPositionY(style, &vDefault);
4186     ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres);
4187
4188     V_VT(&v) = VT_BSTR;
4189     V_BSTR(&v) = a2bstr("10px");
4190     hres = IHTMLStyle_put_backgroundPositionY(style, v);
4191     ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres);
4192     VariantClear(&v);
4193
4194     hres = IHTMLStyle_get_backgroundPositionY(style, &v);
4195     ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres);
4196     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4197     VariantClear(&v);
4198
4199     hres = IHTMLStyle_put_backgroundPositionY(style, vDefault);
4200     ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres);
4201     VariantClear(&vDefault);
4202
4203      /* borderTopWidth */
4204     hres = IHTMLStyle_get_borderTopWidth(style, &vDefault);
4205     ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres);
4206
4207     V_VT(&v) = VT_BSTR;
4208     V_BSTR(&v) = a2bstr("10px");
4209     hres = IHTMLStyle_put_borderTopWidth(style, v);
4210     ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres);
4211     VariantClear(&v);
4212
4213     hres = IHTMLStyle_get_borderTopWidth(style, &v);
4214     ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres);
4215     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4216     VariantClear(&v);
4217
4218     hres = IHTMLStyle_put_borderTopWidth(style, vDefault);
4219     ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres);
4220     VariantClear(&vDefault);
4221
4222     /* borderRightWidth */
4223     hres = IHTMLStyle_get_borderRightWidth(style, &vDefault);
4224     ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres);
4225
4226     V_VT(&v) = VT_BSTR;
4227     V_BSTR(&v) = a2bstr("10");
4228     hres = IHTMLStyle_put_borderRightWidth(style, v);
4229     ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres);
4230     VariantClear(&v);
4231
4232     hres = IHTMLStyle_get_borderRightWidth(style, &v);
4233     ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres);
4234     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4235     VariantClear(&v);
4236
4237     hres = IHTMLStyle_put_borderRightWidth(style, vDefault);
4238     ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres);
4239     VariantClear(&vDefault);
4240
4241     /* borderBottomWidth */
4242     hres = IHTMLStyle_get_borderBottomWidth(style, &vDefault);
4243     ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres);
4244
4245     V_VT(&v) = VT_BSTR;
4246     V_BSTR(&v) = a2bstr("10");
4247     hres = IHTMLStyle_put_borderBottomWidth(style, v);
4248     ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres);
4249     VariantClear(&v);
4250
4251     hres = IHTMLStyle_get_borderBottomWidth(style, &v);
4252     ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres);
4253     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4254     VariantClear(&v);
4255
4256     hres = IHTMLStyle_put_borderBottomWidth(style, vDefault);
4257     ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres);
4258     VariantClear(&vDefault);
4259
4260     /* borderLeftWidth */
4261     hres = IHTMLStyle_get_borderLeftWidth(style, &vDefault);
4262     ok(hres == S_OK, "get_borderLeftWidth: %08x\n", hres);
4263
4264     V_VT(&v) = VT_BSTR;
4265     V_BSTR(&v) = a2bstr("10");
4266     hres = IHTMLStyle_put_borderLeftWidth(style, v);
4267     ok(hres == S_OK, "put_borderLeftWidth: %08x\n", hres);
4268     VariantClear(&v);
4269
4270     hres = IHTMLStyle_get_borderLeftWidth(style, &v);
4271     ok(hres == S_OK, "get_borderLeftWidth: %08x\n", hres);
4272     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4273     VariantClear(&v);
4274
4275     hres = IHTMLStyle_put_borderLeftWidth(style, vDefault);
4276     ok(hres == S_OK, "put_borderLeftWidth: %08x\n", hres);
4277     VariantClear(&vDefault);
4278
4279     /* wordSpacing */
4280     hres = IHTMLStyle_get_wordSpacing(style, &vDefault);
4281     ok(hres == S_OK, "get_wordSpacing: %08x\n", hres);
4282
4283     V_VT(&v) = VT_BSTR;
4284     V_BSTR(&v) = a2bstr("10");
4285     hres = IHTMLStyle_put_wordSpacing(style, v);
4286     ok(hres == S_OK, "put_wordSpacing: %08x\n", hres);
4287     VariantClear(&v);
4288
4289     hres = IHTMLStyle_get_wordSpacing(style, &v);
4290     ok(hres == S_OK, "get_wordSpacing: %08x\n", hres);
4291     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4292     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4293     VariantClear(&v);
4294
4295     hres = IHTMLStyle_put_wordSpacing(style, vDefault);
4296     ok(hres == S_OK, "put_wordSpacing: %08x\n", hres);
4297     VariantClear(&vDefault);
4298
4299     /* letterSpacing */
4300     hres = IHTMLStyle_get_letterSpacing(style, &vDefault);
4301     ok(hres == S_OK, "get_letterSpacing: %08x\n", hres);
4302
4303     V_VT(&v) = VT_BSTR;
4304     V_BSTR(&v) = a2bstr("11");
4305     hres = IHTMLStyle_put_letterSpacing(style, v);
4306     ok(hres == S_OK, "put_letterSpacing: %08x\n", hres);
4307     VariantClear(&v);
4308
4309     hres = IHTMLStyle_get_letterSpacing(style, &v);
4310     ok(hres == S_OK, "get_letterSpacing: %08x\n", hres);
4311     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4312     ok(!strcmp_wa(V_BSTR(&v), "11px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4313     VariantClear(&v);
4314
4315     hres = IHTMLStyle_put_letterSpacing(style, vDefault);
4316     ok(hres == S_OK, "put_letterSpacing: %08x\n", hres);
4317     VariantClear(&vDefault);
4318
4319     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle2, (void**)&style2);
4320     ok(hres == S_OK, "Could not get IHTMLStyle2 iface: %08x\n", hres);
4321     if(SUCCEEDED(hres)) {
4322         test_style2(style2);
4323         IHTMLStyle2_Release(style2);
4324     }
4325
4326     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle3, (void**)&style3);
4327     ok(hres == S_OK, "Could not get IHTMLStyle3 iface: %08x\n", hres);
4328     if(SUCCEEDED(hres)) {
4329         test_style3(style3);
4330         IHTMLStyle3_Release(style3);
4331     }
4332
4333     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle4, (void**)&style4);
4334     ok(hres == S_OK, "Could not get IHTMLStyle4 iface: %08x\n", hres);
4335     if(SUCCEEDED(hres)) {
4336         test_style4(style4);
4337         IHTMLStyle4_Release(style4);
4338     }
4339 }
4340
4341 static void test_set_csstext(IHTMLStyle *style)
4342 {
4343     VARIANT v;
4344     HRESULT hres;
4345
4346     test_style_set_csstext(style, "background-color: black;");
4347
4348     hres = IHTMLStyle_get_backgroundColor(style, &v);
4349     ok(hres == S_OK, "get_backgroundColor: %08x\n", hres);
4350     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4351     ok(!strcmp_wa(V_BSTR(&v), "black"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4352     VariantClear(&v);
4353 }
4354
4355 static void test_default_selection(IHTMLDocument2 *doc)
4356 {
4357     IHTMLSelectionObject *selection;
4358     IHTMLTxtRange *range;
4359     IDispatch *disp;
4360     BSTR str;
4361     HRESULT hres;
4362
4363     hres = IHTMLDocument2_get_selection(doc, &selection);
4364     ok(hres == S_OK, "get_selection failed: %08x\n", hres);
4365
4366     hres = IHTMLSelectionObject_get_type(selection, &str);
4367     ok(hres == S_OK, "get_type failed: %08x\n", hres);
4368     ok(!strcmp_wa(str, "None"), "type = %s\n", wine_dbgstr_w(str));
4369     SysFreeString(str);
4370
4371     hres = IHTMLSelectionObject_createRange(selection, &disp);
4372     IHTMLSelectionObject_Release(selection);
4373     ok(hres == S_OK, "createRange failed: %08x\n", hres);
4374
4375     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTxtRange, (void**)&range);
4376     IDispatch_Release(disp);
4377     ok(hres == S_OK, "Could not get IHTMLTxtRange interface: %08x\n", hres);
4378
4379     test_range_text(range, NULL);
4380     IHTMLTxtRange_Release(range);
4381 }
4382
4383 static void test_doc_elem(IHTMLDocument2 *doc)
4384 {
4385     IHTMLDocument2 *doc_node, *owner_doc;
4386     IHTMLElement *elem;
4387     IHTMLDocument3 *doc3;
4388     HRESULT hres;
4389
4390     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4391     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
4392
4393     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
4394     IHTMLDocument3_Release(doc3);
4395     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
4396
4397     test_node_name((IUnknown*)elem, "HTML");
4398     test_elem_tag((IUnknown*)elem, "HTML");
4399
4400     doc_node = get_doc_node(doc);
4401     owner_doc = get_owner_doc((IUnknown*)elem);
4402     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
4403     IHTMLDocument2_Release(doc_node);
4404     IHTMLDocument2_Release(owner_doc);
4405
4406     test_elem_client_rect((IUnknown*)elem);
4407
4408     IHTMLElement_Release(elem);
4409 }
4410
4411 static void test_default_body(IHTMLBodyElement *body)
4412 {
4413     LONG l;
4414     BSTR bstr;
4415     HRESULT hres;
4416     VARIANT v;
4417     WCHAR sBodyText[] = {'#','F','F','0','0','0','0',0};
4418     WCHAR sTextInvalid[] = {'I','n','v','a','l','i','d',0};
4419
4420     bstr = (void*)0xdeadbeef;
4421     hres = IHTMLBodyElement_get_background(body, &bstr);
4422     ok(hres == S_OK, "get_background failed: %08x\n", hres);
4423     ok(bstr == NULL, "bstr != NULL\n");
4424
4425     l = elem_get_scroll_height((IUnknown*)body);
4426     ok(l != -1, "scrollHeight == -1\n");
4427     l = elem_get_scroll_width((IUnknown*)body);
4428     ok(l != -1, "scrollWidth == -1\n");
4429     l = elem_get_scroll_top((IUnknown*)body);
4430     ok(!l, "scrollTop = %d\n", l);
4431     elem_get_scroll_left((IUnknown*)body);
4432
4433     /* get_text tests */
4434     hres = IHTMLBodyElement_get_text(body, &v);
4435     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4436     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4437     ok(bstr == NULL, "bstr != NULL\n");
4438
4439
4440     /* get_text - Invalid Text */
4441     V_VT(&v) = VT_BSTR;
4442     V_BSTR(&v) = SysAllocString(sTextInvalid);
4443     hres = IHTMLBodyElement_put_text(body, v);
4444     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4445     VariantClear(&v);
4446
4447     V_VT(&v) = VT_NULL;
4448     hres = IHTMLBodyElement_get_text(body, &v);
4449     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4450     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4451     ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v != '#00a0d0'\n");
4452     VariantClear(&v);
4453
4454     /* get_text - Valid Text */
4455     V_VT(&v) = VT_BSTR;
4456     V_BSTR(&v) = SysAllocString(sBodyText);
4457     hres = IHTMLBodyElement_put_text(body, v);
4458     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4459     VariantClear(&v);
4460
4461     V_VT(&v) = VT_NULL;
4462     hres = IHTMLBodyElement_get_text(body, &v);
4463     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4464     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4465     ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v != '#ff0000'\n");
4466     VariantClear(&v);
4467 }
4468
4469 static void test_body_funs(IHTMLBodyElement *body)
4470 {
4471     static WCHAR sRed[] = {'r','e','d',0};
4472     VARIANT vbg;
4473     VARIANT vDefaultbg;
4474     HRESULT hres;
4475
4476     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
4477     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4478     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
4479
4480     V_VT(&vbg) = VT_BSTR;
4481     V_BSTR(&vbg) = SysAllocString(sRed);
4482     hres = IHTMLBodyElement_put_bgColor(body, vbg);
4483     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4484     VariantClear(&vbg);
4485
4486     hres = IHTMLBodyElement_get_bgColor(body, &vbg);
4487     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4488     ok(V_VT(&vDefaultbg) == VT_BSTR, "V_VT(&vDefaultbg) != VT_BSTR\n");
4489     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
4490     VariantClear(&vbg);
4491
4492     /* Restore Originial */
4493     hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg);
4494     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4495     VariantClear(&vDefaultbg);
4496 }
4497
4498 static void test_window(IHTMLDocument2 *doc)
4499 {
4500     IHTMLWindow2 *window, *window2, *self;
4501     IHTMLDocument2 *doc2 = NULL;
4502     IDispatch *disp;
4503     IUnknown *unk;
4504     BSTR str;
4505     HRESULT hres;
4506
4507     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4508     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
4509     test_ifaces((IUnknown*)window, window_iids);
4510     test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, "[object]");
4511
4512     hres = IHTMLWindow2_get_document(window, &doc2);
4513     ok(hres == S_OK, "get_document failed: %08x\n", hres);
4514     ok(doc2 != NULL, "doc2 == NULL\n");
4515
4516     test_ifaces((IUnknown*)doc2, doc_node_iids);
4517     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
4518
4519     test_ifaces((IUnknown*)doc, doc_obj_iids);
4520     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
4521
4522     unk = (void*)0xdeadbeef;
4523     hres = IHTMLDocument2_QueryInterface(doc2, &IID_ICustomDoc, (void**)&unk);
4524     ok(hres == E_NOINTERFACE, "QueryInterface(IID_ICustomDoc) returned: %08x\n", hres);
4525     ok(!unk, "unk = %p\n", unk);
4526
4527     IHTMLDocument_Release(doc2);
4528
4529     hres = IHTMLWindow2_get_window(window, &window2);
4530     ok(hres == S_OK, "get_window failed: %08x\n", hres);
4531     ok(window2 != NULL, "window2 == NULL\n");
4532
4533     hres = IHTMLWindow2_get_self(window, &self);
4534     ok(hres == S_OK, "get_self failed: %08x\n", hres);
4535     ok(window2 != NULL, "self == NULL\n");
4536
4537     ok(self == window2, "self != window2\n");
4538
4539     IHTMLWindow2_Release(window2);
4540     IHTMLWindow2_Release(self);
4541
4542     disp = NULL;
4543     hres = IHTMLDocument2_get_Script(doc, &disp);
4544     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
4545     ok(disp == (void*)window, "disp != window\n");
4546     IDispatch_Release(disp);
4547
4548     hres = IHTMLWindow2_toString(window, NULL);
4549     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
4550
4551     str = NULL;
4552     hres = IHTMLWindow2_toString(window, &str);
4553     ok(hres == S_OK, "toString failed: %08x\n", hres);
4554     ok(!strcmp_wa(str, "[object]"), "toString returned %s\n", wine_dbgstr_w(str));
4555     SysFreeString(str);
4556
4557     test_window_name(window, NULL);
4558     set_window_name(window, "test");
4559     test_window_length(window, 0);
4560
4561     IHTMLWindow2_Release(window);
4562 }
4563
4564 static void test_defaults(IHTMLDocument2 *doc)
4565 {
4566     IHTMLStyleSheetsCollection *stylesheetcol;
4567     IHTMLCurrentStyle *cstyle;
4568     IHTMLBodyElement *body;
4569     IHTMLElement2 *elem2;
4570     IHTMLElement *elem;
4571     IHTMLStyle *style;
4572     LONG l;
4573     HRESULT hres;
4574     IHTMLElementCollection *collection;
4575
4576     hres = IHTMLDocument2_get_body(doc, &elem);
4577     ok(hres == S_OK, "get_body failed: %08x\n", hres);
4578
4579     hres = IHTMLDocument2_get_images(doc, NULL);
4580     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4581
4582     hres = IHTMLDocument2_get_images(doc, &collection);
4583     ok(hres == S_OK, "get_images failed: %08x\n", hres);
4584     if(hres == S_OK)
4585     {
4586         test_elem_collection((IUnknown*)collection, NULL, 0);
4587         IHTMLElementCollection_Release(collection);
4588     }
4589
4590     hres = IHTMLDocument2_get_applets(doc, NULL);
4591     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4592
4593     hres = IHTMLDocument2_get_applets(doc, &collection);
4594     ok(hres == S_OK, "get_applets failed: %08x\n", hres);
4595     if(hres == S_OK)
4596     {
4597         test_elem_collection((IUnknown*)collection, NULL, 0);
4598         IHTMLElementCollection_Release(collection);
4599     }
4600
4601     hres = IHTMLDocument2_get_links(doc, NULL);
4602     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4603
4604     hres = IHTMLDocument2_get_links(doc, &collection);
4605     ok(hres == S_OK, "get_links failed: %08x\n", hres);
4606     if(hres == S_OK)
4607     {
4608         test_elem_collection((IUnknown*)collection, NULL, 0);
4609         IHTMLElementCollection_Release(collection);
4610     }
4611
4612     hres = IHTMLDocument2_get_forms(doc, NULL);
4613     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4614
4615     hres = IHTMLDocument2_get_forms(doc, &collection);
4616     ok(hres == S_OK, "get_forms failed: %08x\n", hres);
4617     if(hres == S_OK)
4618     {
4619         test_elem_collection((IUnknown*)collection, NULL, 0);
4620         IHTMLElementCollection_Release(collection);
4621     }
4622
4623     hres = IHTMLDocument2_get_anchors(doc, NULL);
4624     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4625
4626     hres = IHTMLDocument2_get_anchors(doc, &collection);
4627     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
4628     if(hres == S_OK)
4629     {
4630         test_elem_collection((IUnknown*)collection, NULL, 0);
4631         IHTMLElementCollection_Release(collection);
4632     }
4633
4634     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
4635     ok(hres == S_OK, "Could not get IHTMBodyElement: %08x\n", hres);
4636     test_default_body(body);
4637     test_body_funs(body);
4638     IHTMLBodyElement_Release(body);
4639
4640     hres = IHTMLElement_get_style(elem, &style);
4641     ok(hres == S_OK, "get_style failed: %08x\n", hres);
4642
4643     test_default_style(style);
4644     test_window(doc);
4645     test_compatmode(doc);
4646     test_location(doc);
4647     test_navigator(doc);
4648
4649     elem2 = get_elem2_iface((IUnknown*)elem);
4650     hres = IHTMLElement2_get_currentStyle(elem2, &cstyle);
4651     ok(hres == S_OK, "get_currentStyle failed: %08x\n", hres);
4652     if(SUCCEEDED(hres)) {
4653         test_current_style(cstyle);
4654         IHTMLCurrentStyle_Release(cstyle);
4655     }
4656     IHTMLElement2_Release(elem2);
4657
4658     IHTMLElement_Release(elem);
4659
4660     test_set_csstext(style);
4661     IHTMLStyle_Release(style);
4662
4663     hres = IHTMLDocument2_get_styleSheets(doc, &stylesheetcol);
4664     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
4665
4666     l = 0xdeadbeef;
4667     hres = IHTMLStyleSheetsCollection_get_length(stylesheetcol, &l);
4668     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4669     ok(l == 0, "length = %d\n", l);
4670
4671     IHTMLStyleSheetsCollection_Release(stylesheetcol);
4672
4673     test_default_selection(doc);
4674     test_doc_title(doc, "");
4675 }
4676
4677 static void test_tr_elem(IHTMLElement *elem)
4678 {
4679     IHTMLElementCollection *col;
4680     IHTMLTableRow *row;
4681     HRESULT hres;
4682
4683     static const elem_type_t cell_types[] = {ET_TD,ET_TD};
4684
4685     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableRow, (void**)&row);
4686     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
4687     if(FAILED(hres))
4688         return;
4689
4690     col = NULL;
4691     hres = IHTMLTableRow_get_cells(row, &col);
4692     ok(hres == S_OK, "get_cells failed: %08x\n", hres);
4693     ok(col != NULL, "get_cells returned NULL\n");
4694
4695     test_elem_collection((IUnknown*)col, cell_types, sizeof(cell_types)/sizeof(*cell_types));
4696     IHTMLElementCollection_Release(col);
4697
4698     IHTMLTable_Release(row);
4699 }
4700
4701 static void test_table_elem(IHTMLElement *elem)
4702 {
4703     IHTMLElementCollection *col;
4704     IHTMLTable *table;
4705     IHTMLDOMNode *node;
4706     HRESULT hres;
4707
4708     static const elem_type_t row_types[] = {ET_TR,ET_TR};
4709     static const elem_type_t all_types[] = {ET_TBODY,ET_TR,ET_TR,ET_TD,ET_TD};
4710
4711     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable, (void**)&table);
4712     ok(hres == S_OK, "Could not get IHTMLTable iface: %08x\n", hres);
4713     if(FAILED(hres))
4714         return;
4715
4716     col = NULL;
4717     hres = IHTMLTable_get_rows(table, &col);
4718     ok(hres == S_OK, "get_rows failed: %08x\n", hres);
4719     ok(col != NULL, "get_ros returned NULL\n");
4720
4721     test_elem_collection((IUnknown*)col, row_types, sizeof(row_types)/sizeof(*row_types));
4722     IHTMLElementCollection_Release(col);
4723
4724     test_elem_all((IUnknown*)table, all_types, sizeof(all_types)/sizeof(*all_types));
4725
4726     node = clone_node((IUnknown*)table, VARIANT_TRUE);
4727     test_elem_tag((IUnknown*)node, "TABLE");
4728     test_elem_all((IUnknown*)node, all_types, sizeof(all_types)/sizeof(*all_types));
4729     IHTMLDOMNode_Release(node);
4730
4731     node = clone_node((IUnknown*)table, VARIANT_FALSE);
4732     test_elem_tag((IUnknown*)node, "TABLE");
4733     test_elem_all((IUnknown*)node, NULL, 0);
4734     IHTMLDOMNode_Release(node);
4735
4736     IHTMLTable_Release(table);
4737 }
4738
4739 static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
4740 {
4741     SAFEARRAYBOUND dim;
4742     SAFEARRAY *sa;
4743     VARIANT *var;
4744     BSTR str;
4745     HRESULT hres;
4746
4747     dim.lLbound = 0;
4748     dim.cElements = 1;
4749     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
4750     SafeArrayAccessData(sa, (void**)&var);
4751     V_VT(var) = VT_BSTR;
4752     V_BSTR(var) = str = a2bstr(text);
4753     SafeArrayUnaccessData(sa);
4754
4755     if(ln)
4756         hres = IHTMLDocument2_writeln(doc, sa);
4757     else
4758         hres = IHTMLDocument2_write(doc, sa);
4759     ok(hres == S_OK, "write failed: %08x\n", hres);
4760
4761     SysFreeString(str);
4762     SafeArrayDestroy(sa);
4763 }
4764
4765 static void test_iframe_elem(IHTMLElement *elem)
4766 {
4767     IHTMLElementCollection *col;
4768     IHTMLDocument2 *content_doc;
4769     IHTMLWindow2 *content_window;
4770     IHTMLFrameBase2 *base2;
4771     IDispatch *disp;
4772     VARIANT errv;
4773     BSTR str;
4774     HRESULT hres;
4775
4776     static const elem_type_t all_types[] = {
4777         ET_HTML,
4778         ET_HEAD,
4779         ET_TITLE,
4780         ET_BODY,
4781         ET_BR
4782     };
4783
4784     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
4785     ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
4786     if (!base2) return;
4787
4788     content_window = NULL;
4789     hres = IHTMLFrameBase2_get_contentWindow(base2, &content_window);
4790     IHTMLFrameBase2_Release(base2);
4791     ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
4792     ok(content_window != NULL, "contentWindow = NULL\n");
4793
4794     test_window_length(content_window, 0);
4795
4796     content_doc = NULL;
4797     hres = IHTMLWindow2_get_document(content_window, &content_doc);
4798     IHTMLWindow2_Release(content_window);
4799     ok(hres == S_OK, "get_document failed: %08x\n", hres);
4800     ok(content_doc != NULL, "content_doc = NULL\n");
4801
4802     str = a2bstr("text/html");
4803     V_VT(&errv) = VT_ERROR;
4804     disp = NULL;
4805     hres = IHTMLDocument2_open(content_doc, str, errv, errv, errv, &disp);
4806     SysFreeString(str);
4807     ok(hres == S_OK, "open failed: %08x\n", hres);
4808     ok(disp != NULL, "disp == NULL\n");
4809     ok(iface_cmp((IUnknown*)disp, (IUnknown*)content_window), "disp != content_window\n");
4810     IDispatch_Release(disp);
4811
4812     doc_write(content_doc, FALSE, "<html><head><title>test</title></head><body><br /></body>");
4813     doc_write(content_doc, TRUE, "</html>");
4814
4815     hres = IHTMLDocument2_get_all(content_doc, &col);
4816     ok(hres == S_OK, "get_all failed: %08x\n", hres);
4817     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
4818     IHTMLElementCollection_Release(col);
4819
4820     hres = IHTMLDocument2_close(content_doc);
4821     ok(hres == S_OK, "close failed: %08x\n", hres);
4822
4823     IHTMLDocument2_Release(content_doc);
4824 }
4825
4826 static void test_stylesheet(IDispatch *disp)
4827 {
4828     IHTMLStyleSheetRulesCollection *col = NULL;
4829     IHTMLStyleSheet *stylesheet;
4830     HRESULT hres;
4831
4832     hres = IDispatch_QueryInterface(disp, &IID_IHTMLStyleSheet, (void**)&stylesheet);
4833     ok(hres == S_OK, "Could not get IHTMLStyleSheet: %08x\n", hres);
4834
4835     hres = IHTMLStyleSheet_get_rules(stylesheet, &col);
4836     ok(hres == S_OK, "get_rules failed: %08x\n", hres);
4837     ok(col != NULL, "col == NULL\n");
4838
4839     IHTMLStyleSheetRulesCollection_Release(col);
4840     IHTMLStyleSheet_Release(stylesheet);
4841 }
4842
4843 static void test_stylesheets(IHTMLDocument2 *doc)
4844 {
4845     IHTMLStyleSheetsCollection *col = NULL;
4846     VARIANT idx, res;
4847     LONG len = 0;
4848     HRESULT hres;
4849
4850     hres = IHTMLDocument2_get_styleSheets(doc, &col);
4851     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
4852     ok(col != NULL, "col == NULL\n");
4853
4854     hres = IHTMLStyleSheetsCollection_get_length(col, &len);
4855     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4856     ok(len == 1, "len=%d\n", len);
4857
4858     VariantInit(&res);
4859     V_VT(&idx) = VT_I4;
4860     V_I4(&idx) = 0;
4861
4862     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
4863     ok(hres == S_OK, "item failed: %08x\n", hres);
4864     ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
4865     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
4866     test_stylesheet(V_DISPATCH(&res));
4867     VariantClear(&res);
4868
4869     V_VT(&res) = VT_I4;
4870     V_VT(&idx) = VT_I4;
4871     V_I4(&idx) = 1;
4872
4873     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
4874     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4875     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
4876     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
4877     VariantClear(&res);
4878
4879     IHTMLStyleSheetsCollection_Release(col);
4880 }
4881
4882 static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
4883 {
4884     IDispatchEx *dispex;
4885     IHTMLDOMNode *node;
4886     DISPPARAMS dp = {NULL, NULL, 0, 0};
4887     VARIANT var;
4888     EXCEPINFO ei;
4889     LONG type;
4890     DISPID id;
4891     BSTR bstr;
4892     HRESULT hres;
4893
4894     static const WCHAR w0[] = {'0',0};
4895     static const WCHAR w100[] = {'1','0','0',0};
4896
4897     hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
4898     ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
4899
4900     bstr = SysAllocString(w0);
4901     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
4902     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
4903     SysFreeString(bstr);
4904
4905     VariantInit(&var);
4906     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
4907     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
4908     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
4909     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
4910     node = get_node_iface((IUnknown*)V_DISPATCH(&var));
4911     type = get_node_type((IUnknown*)node);
4912     ok(type == 3, "type=%d\n", type);
4913     IHTMLDOMNode_Release(node);
4914     VariantClear(&var);
4915
4916     bstr = SysAllocString(w100);
4917     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
4918     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
4919     SysFreeString(bstr);
4920
4921     IDispatchEx_Release(dispex);
4922 }
4923
4924
4925
4926 static void test_elems(IHTMLDocument2 *doc)
4927 {
4928     IHTMLElementCollection *col;
4929     IHTMLDOMChildrenCollection *child_col;
4930     IHTMLElement *elem, *elem2, *elem3;
4931     IHTMLDOMNode *node, *node2;
4932     IHTMLWindow2 *window;
4933     IDispatch *disp;
4934     LONG type;
4935     HRESULT hres;
4936     IHTMLElementCollection *collection;
4937     IHTMLDocument3 *doc3;
4938     BSTR str;
4939
4940     static const elem_type_t all_types[] = {
4941         ET_HTML,
4942         ET_HEAD,
4943         ET_TITLE,
4944         ET_STYLE,
4945         ET_BODY,
4946         ET_COMMENT,
4947         ET_A,
4948         ET_INPUT,
4949         ET_SELECT,
4950         ET_OPTION,
4951         ET_OPTION,
4952         ET_TEXTAREA,
4953         ET_TABLE,
4954         ET_TBODY,
4955         ET_TR,
4956         ET_TR,
4957         ET_TD,
4958         ET_TD,
4959         ET_SCRIPT,
4960         ET_TEST,
4961         ET_IMG,
4962         ET_IFRAME
4963     };
4964
4965     static const elem_type_t item_types[] = {
4966         ET_A,
4967         ET_OPTION,
4968         ET_TEXTAREA
4969     };
4970
4971     hres = IHTMLDocument2_get_all(doc, &col);
4972     ok(hres == S_OK, "get_all failed: %08x\n", hres);
4973     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
4974     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
4975     IHTMLElementCollection_Release(col);
4976
4977     hres = IHTMLDocument2_get_images(doc, &collection);
4978     ok(hres == S_OK, "get_images failed: %08x\n", hres);
4979     if(hres == S_OK)
4980     {
4981         static const elem_type_t images_types[] = {ET_IMG};
4982         test_elem_collection((IUnknown*)collection, images_types, 1);
4983
4984         IHTMLElementCollection_Release(collection);
4985     }
4986
4987     hres = IHTMLDocument2_get_links(doc, &collection);
4988     ok(hres == S_OK, "get_links failed: %08x\n", hres);
4989     if(hres == S_OK)
4990     {
4991         static const elem_type_t images_types[] = {ET_A};
4992         test_elem_collection((IUnknown*)collection, images_types, 1);
4993
4994         IHTMLElementCollection_Release(collection);
4995     }
4996
4997     hres = IHTMLDocument2_get_anchors(doc, &collection);
4998     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
4999     if(hres == S_OK)
5000     {
5001         static const elem_type_t anchor_types[] = {ET_A};
5002         test_elem_collection((IUnknown*)collection, anchor_types, 1);
5003
5004         IHTMLElementCollection_Release(collection);
5005     }
5006
5007     elem = get_doc_elem(doc);
5008     test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1);
5009     IHTMLElement_Release(elem);
5010
5011     get_elem_by_id(doc, "xxx", FALSE);
5012     elem = get_doc_elem_by_id(doc, "xxx");
5013     ok(!elem, "elem != NULL\n");
5014
5015     elem = get_doc_elem_by_id(doc, "s");
5016     ok(elem != NULL, "elem == NULL\n");
5017     if(elem) {
5018         test_elem_type((IUnknown*)elem, ET_SELECT);
5019         test_elem_attr(elem, "xxx", NULL);
5020         test_elem_attr(elem, "id", "s");
5021         test_elem_class((IUnknown*)elem, NULL);
5022         test_elem_set_class((IUnknown*)elem, "cl");
5023         test_elem_set_class((IUnknown*)elem, NULL);
5024         test_elem_tabindex((IUnknown*)elem, 0);
5025         test_elem_set_tabindex((IUnknown*)elem, 1);
5026
5027         node = test_node_get_parent((IUnknown*)elem);
5028         ok(node != NULL, "node == NULL\n");
5029         test_node_name((IUnknown*)node, "BODY");
5030         node2 = test_node_get_parent((IUnknown*)node);
5031         IHTMLDOMNode_Release(node);
5032         ok(node2 != NULL, "node == NULL\n");
5033         test_node_name((IUnknown*)node2, "HTML");
5034         node = test_node_get_parent((IUnknown*)node2);
5035         IHTMLDOMNode_Release(node2);
5036         ok(node != NULL, "node == NULL\n");
5037         if (node)
5038         {
5039             test_node_name((IUnknown*)node, "#document");
5040             type = get_node_type((IUnknown*)node);
5041             ok(type == 9, "type=%d, expected 9\n", type);
5042             node2 = test_node_get_parent((IUnknown*)node);
5043             IHTMLDOMNode_Release(node);
5044             ok(node2 == NULL, "node != NULL\n");
5045         }
5046
5047         elem2 = test_elem_get_parent((IUnknown*)elem);
5048         ok(elem2 != NULL, "elem2 == NULL\n");
5049         test_node_name((IUnknown*)elem2, "BODY");
5050         elem3 = test_elem_get_parent((IUnknown*)elem2);
5051         IHTMLElement_Release(elem2);
5052         ok(elem3 != NULL, "elem3 == NULL\n");
5053         test_node_name((IUnknown*)elem3, "HTML");
5054         elem2 = test_elem_get_parent((IUnknown*)elem3);
5055         IHTMLElement_Release(elem3);
5056         ok(elem2 == NULL, "elem2 != NULL\n");
5057
5058         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2);
5059         test_elem_getelembytag((IUnknown*)elem, ET_SELECT, 0);
5060         test_elem_getelembytag((IUnknown*)elem, ET_HTML, 0);
5061
5062         test_elem_innertext(elem, "opt1opt2");
5063
5064         IHTMLElement_Release(elem);
5065     }
5066
5067     elem = get_elem_by_id(doc, "s", TRUE);
5068     if(elem) {
5069         IHTMLSelectElement *select;
5070         IHTMLDocument2 *doc_node;
5071
5072         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select);
5073         ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres);
5074
5075         test_select_elem(select);
5076
5077         test_elem_title((IUnknown*)select, NULL);
5078         test_elem_set_title((IUnknown*)select, "Title");
5079         test_elem_title((IUnknown*)select, "Title");
5080         test_elem_offset((IUnknown*)select);
5081
5082         node = get_first_child((IUnknown*)select);
5083         ok(node != NULL, "node == NULL\n");
5084         if(node) {
5085             test_elem_type((IUnknown*)node, ET_OPTION);
5086             IHTMLDOMNode_Release(node);
5087         }
5088
5089         type = get_node_type((IUnknown*)select);
5090         ok(type == 1, "type=%d\n", type);
5091
5092         IHTMLSelectElement_Release(select);
5093
5094         hres = IHTMLElement_get_document(elem, &disp);
5095         ok(hres == S_OK, "get_document failed: %08x\n", hres);
5096
5097         doc_node = get_doc_node(doc);
5098         ok(iface_cmp((IUnknown*)disp, (IUnknown*)doc_node), "disp != doc\n");
5099         IHTMLDocument2_Release(doc_node);
5100
5101         IHTMLElement_Release(elem);
5102     }
5103
5104     elem = get_elem_by_id(doc, "sc", TRUE);
5105     if(elem) {
5106         IHTMLScriptElement *script;
5107         BSTR type;
5108
5109         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLScriptElement, (void**)&script);
5110         ok(hres == S_OK, "Could not get IHTMLScriptElement interface: %08x\n", hres);
5111
5112         if(hres == S_OK)
5113         {
5114             VARIANT_BOOL vb;
5115
5116             hres = IHTMLScriptElement_get_type(script, &type);
5117             ok(hres == S_OK, "get_type failed: %08x\n", hres);
5118             ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type));
5119             SysFreeString(type);
5120
5121             /* test defer */
5122             hres = IHTMLScriptElement_put_defer(script, VARIANT_TRUE);
5123             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5124
5125             hres = IHTMLScriptElement_get_defer(script, &vb);
5126             ok(hres == S_OK, "get_defer failed: %08x\n", hres);
5127             ok(vb == VARIANT_TRUE, "get_defer result is %08x\n", hres);
5128
5129             hres = IHTMLScriptElement_put_defer(script, VARIANT_FALSE);
5130             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5131         }
5132
5133         IHTMLScriptElement_Release(script);
5134     }
5135
5136     elem = get_elem_by_id(doc, "in", TRUE);
5137     if(elem) {
5138         IHTMLInputElement *input;
5139
5140         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLInputElement, (void**)&input);
5141         ok(hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
5142
5143         test_elem_id((IUnknown*)elem, "in");
5144         test_elem_put_id((IUnknown*)elem, "newin");
5145         test_input_get_disabled(input, VARIANT_FALSE);
5146         test_input_set_disabled(input, VARIANT_TRUE);
5147         test_input_set_disabled(input, VARIANT_FALSE);
5148         test_elem3_set_disabled((IUnknown*)input, VARIANT_TRUE);
5149         test_input_get_disabled(input, VARIANT_TRUE);
5150         test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE);
5151         test_input_get_disabled(input, VARIANT_FALSE);
5152         test_elem_client_size((IUnknown*)elem);
5153
5154         test_node_get_value_str((IUnknown*)elem, NULL);
5155         test_node_put_value_str((IUnknown*)elem, "test");
5156         test_node_get_value_str((IUnknown*)elem, NULL);
5157         test_input_value((IUnknown*)elem, NULL);
5158         test_input_put_value((IUnknown*)elem, "test");
5159         test_input_value((IUnknown*)elem, NULL);
5160         test_elem_class((IUnknown*)elem, "testclass");
5161         test_elem_tabindex((IUnknown*)elem, 2);
5162         test_elem_set_tabindex((IUnknown*)elem, 3);
5163         test_elem_title((IUnknown*)elem, "test title");
5164
5165         test_input_get_defaultchecked(input, VARIANT_FALSE);
5166         test_input_set_defaultchecked(input, VARIANT_TRUE);
5167         test_input_set_defaultchecked(input, VARIANT_FALSE);
5168
5169         test_input_get_checked(input, VARIANT_FALSE);
5170         test_input_set_checked(input, VARIANT_TRUE);
5171         test_input_set_checked(input, VARIANT_FALSE);
5172
5173         test_input_src(input, NULL);
5174         test_input_set_src(input, "about:blank");
5175
5176         IHTMLInputElement_Release(input);
5177         IHTMLElement_Release(elem);
5178     }
5179
5180     elem = get_elem_by_id(doc, "imgid", TRUE);
5181     if(elem) {
5182         test_img_src((IUnknown*)elem, "");
5183         test_img_set_src((IUnknown*)elem, "about:blank");
5184         test_img_alt((IUnknown*)elem, NULL);
5185         test_img_set_alt((IUnknown*)elem, "alt test");
5186         IHTMLElement_Release(elem);
5187     }
5188
5189     elem = get_doc_elem_by_id(doc, "tbl");
5190     ok(elem != NULL, "elem == NULL\n");
5191     if(elem) {
5192         test_table_elem(elem);
5193         IHTMLElement_Release(elem);
5194     }
5195
5196     elem = get_doc_elem_by_id(doc, "row2");
5197     ok(elem != NULL, "elem == NULL\n");
5198     if(elem) {
5199         test_tr_elem(elem);
5200         IHTMLElement_Release(elem);
5201     }
5202
5203     elem = get_doc_elem_by_id(doc, "ifr");
5204     ok(elem != NULL, "elem == NULL\n");
5205     if(elem) {
5206         test_iframe_elem(elem);
5207         IHTMLElement_Release(elem);
5208     }
5209
5210     elem = get_elem_by_id(doc, "a", TRUE);
5211     if(elem) {
5212         test_anchor_href((IUnknown*)elem, "http://test/");
5213         IHTMLElement_Release(elem);
5214     }
5215
5216     hres = IHTMLDocument2_get_body(doc, &elem);
5217     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5218
5219     node = get_first_child((IUnknown*)elem);
5220     ok(node != NULL, "node == NULL\n");
5221     if(node) {
5222         test_ifaces((IUnknown*)node, text_iids);
5223         test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
5224
5225         node2 = get_first_child((IUnknown*)node);
5226         ok(!node2, "node2 != NULL\n");
5227
5228         type = get_node_type((IUnknown*)node);
5229         ok(type == 3, "type=%d\n", type);
5230
5231         test_node_get_value_str((IUnknown*)node, "text test");
5232         test_node_put_value_str((IUnknown*)elem, "test text");
5233         test_node_get_value_str((IUnknown*)node, "text test");
5234
5235         IHTMLDOMNode_Release(node);
5236     }
5237
5238     child_col = get_child_nodes((IUnknown*)elem);
5239     ok(child_col != NULL, "child_coll == NULL\n");
5240     if(child_col) {
5241         LONG length = 0;
5242
5243         test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]");
5244
5245         hres = IHTMLDOMChildrenCollection_get_length(child_col, &length);
5246         ok(hres == S_OK, "get_length failed: %08x\n", hres);
5247         ok(length, "length=0\n");
5248
5249         node = get_child_item(child_col, 0);
5250         ok(node != NULL, "node == NULL\n");
5251         if(node) {
5252             type = get_node_type((IUnknown*)node);
5253             ok(type == 3, "type=%d\n", type);
5254             IHTMLDOMNode_Release(node);
5255         }
5256
5257         node = get_child_item(child_col, 1);
5258         ok(node != NULL, "node == NULL\n");
5259         if(node) {
5260             type = get_node_type((IUnknown*)node);
5261             ok(type == 8, "type=%d\n", type);
5262
5263             test_elem_id((IUnknown*)node, NULL);
5264             IHTMLDOMNode_Release(node);
5265         }
5266
5267         hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL);
5268         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
5269
5270         hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL);
5271         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
5272
5273         hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp);
5274         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5275
5276         hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp);
5277         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5278
5279         test_child_col_disp(child_col);
5280
5281         IHTMLDOMChildrenCollection_Release(child_col);
5282     }
5283
5284     test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
5285     test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
5286     test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
5287
5288     IHTMLElement_Release(elem);
5289
5290     test_stylesheets(doc);
5291     test_create_option_elem(doc);
5292     test_create_img_elem(doc);
5293
5294     elem = get_doc_elem_by_id(doc, "tbl");
5295     ok(elem != NULL, "elem = NULL\n");
5296     test_elem_set_innertext(elem, "inner text");
5297     IHTMLElement_Release(elem);
5298
5299     test_doc_title(doc, "test");
5300     test_doc_set_title(doc, "test title");
5301     test_doc_title(doc, "test title");
5302
5303     disp = NULL;
5304     hres = IHTMLDocument2_get_Script(doc, &disp);
5305     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
5306     if(hres == S_OK)
5307     {
5308         IDispatchEx *dispex;
5309         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
5310         ok(hres == S_OK, "IDispatch_QueryInterface failed: %08x\n", hres);
5311         if(hres == S_OK)
5312         {
5313             DISPID pid = -1;
5314             BSTR str = a2bstr("Testing");
5315             hres = IDispatchEx_GetDispID(dispex, str, 1, &pid);
5316             ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5317             ok(pid != -1, "pid == -1\n");
5318             SysFreeString(str);
5319             IDispatchEx_Release(dispex);
5320         }
5321     }
5322     IDispatch_Release(disp);
5323
5324     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
5325     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
5326
5327     str = a2bstr("img");
5328     hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col);
5329     ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres);
5330     SysFreeString(str);
5331     if(hres == S_OK)
5332     {
5333         static const elem_type_t img_types[] = { ET_IMG };
5334
5335         test_elem_collection((IUnknown*)col, img_types, sizeof(img_types)/sizeof(img_types[0]));
5336         IHTMLElementCollection_Release(col);
5337     }
5338
5339     elem = get_doc_elem_by_id(doc, "y");
5340     test_elem_set_innerhtml((IUnknown*)elem, "inner html");
5341     test_elem_innerhtml((IUnknown*)elem, "inner html");
5342     test_elem_set_innerhtml((IUnknown*)elem, "");
5343     test_elem_innerhtml((IUnknown*)elem, NULL);
5344     IHTMLElement_Release(elem);
5345
5346     IHTMLDocument3_Release(doc3);
5347
5348     window = get_doc_window(doc);
5349     test_window_name(window, NULL);
5350     set_window_name(window, "test name");
5351     test_window_length(window, 1);
5352     IHTMLWindow2_Release(window);
5353 }
5354
5355 static void test_create_elems(IHTMLDocument2 *doc)
5356 {
5357     IHTMLElement *elem, *body, *elem2;
5358     IHTMLDOMNode *node, *node2, *node3, *comment;
5359     IHTMLDocument5 *doc5;
5360     IDispatch *disp;
5361     VARIANT var;
5362     LONG type;
5363     HRESULT hres;
5364     BSTR str;
5365
5366     static const elem_type_t types1[] = { ET_TESTG };
5367
5368     elem = test_create_elem(doc, "TEST");
5369     test_elem_tag((IUnknown*)elem, "TEST");
5370     type = get_node_type((IUnknown*)elem);
5371     ok(type == 1, "type=%d\n", type);
5372     test_ifaces((IUnknown*)elem, elem_iids);
5373     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
5374
5375     hres = IHTMLDocument2_get_body(doc, &body);
5376     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5377     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
5378
5379     node = test_node_append_child((IUnknown*)body, (IUnknown*)elem);
5380     test_node_has_child((IUnknown*)body, VARIANT_TRUE);
5381     elem2 = get_elem_iface((IUnknown*)node);
5382     IHTMLElement_Release(elem2);
5383
5384     hres = IHTMLElement_get_all(body, &disp);
5385     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5386     test_elem_collection((IUnknown*)disp, types1, sizeof(types1)/sizeof(types1[0]));
5387     IDispatch_Release(disp);
5388
5389     test_node_remove_child((IUnknown*)body, node);
5390
5391     hres = IHTMLElement_get_all(body, &disp);
5392     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5393     test_elem_collection((IUnknown*)disp, NULL, 0);
5394     IDispatch_Release(disp);
5395     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
5396
5397     IHTMLElement_Release(elem);
5398     IHTMLDOMNode_Release(node);
5399
5400     node = test_create_text(doc, "test");
5401     test_ifaces((IUnknown*)node, text_iids);
5402     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
5403
5404     V_VT(&var) = VT_NULL;
5405     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
5406     IHTMLDOMNode_Release(node);
5407
5408     node = test_create_text(doc, "insert ");
5409
5410     V_VT(&var) = VT_DISPATCH;
5411     V_DISPATCH(&var) = (IDispatch*)node2;
5412     node3 = test_node_insertbefore((IUnknown*)body, node, &var);
5413     IHTMLDOMNode_Release(node);
5414     IHTMLDOMNode_Release(node2);
5415     IHTMLDOMNode_Release(node3);
5416
5417     test_elem_innertext(body, "insert test");
5418     test_elem_innerhtml((IUnknown*)body, "insert test");
5419
5420     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
5421     if(hres == S_OK)
5422     {
5423         str = a2bstr("testing");
5424         hres = IHTMLDocument5_createComment(doc5, str, &comment);
5425         SysFreeString(str);
5426         ok(hres == S_OK, "createComment failed: %08x\n", hres);
5427         if(hres == S_OK)
5428         {
5429             type = get_node_type((IUnknown*)comment);
5430             ok(type == 8, "type=%d, expected 8\n", type);
5431
5432             test_node_get_value_str((IUnknown*)comment, "testing");
5433
5434             IHTMLDOMNode_Release(comment);
5435         }
5436
5437         IHTMLDocument5_Release(doc5);
5438     }
5439
5440     IHTMLElement_Release(body);
5441 }
5442
5443 static void test_exec(IUnknown *unk, const GUID *grpid, DWORD cmdid, VARIANT *in, VARIANT *out)
5444 {
5445     IOleCommandTarget *cmdtrg;
5446     HRESULT hres;
5447
5448     hres = IHTMLTxtRange_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
5449     ok(hres == S_OK, "Could not get IOleCommandTarget interface: %08x\n", hres);
5450
5451     hres = IOleCommandTarget_Exec(cmdtrg, grpid, cmdid, 0, in, out);
5452     ok(hres == S_OK, "Exec failed: %08x\n", hres);
5453
5454     IOleCommandTarget_Release(cmdtrg);
5455 }
5456
5457 static void test_indent(IHTMLDocument2 *doc)
5458 {
5459     IHTMLElementCollection *col;
5460     IHTMLTxtRange *range;
5461     HRESULT hres;
5462
5463     static const elem_type_t all_types[] = {
5464         ET_HTML,
5465         ET_HEAD,
5466         ET_TITLE,
5467         ET_BODY,
5468         ET_BR,
5469         ET_A,
5470     };
5471
5472     static const elem_type_t indent_types[] = {
5473         ET_HTML,
5474         ET_HEAD,
5475         ET_TITLE,
5476         ET_BODY,
5477         ET_BLOCKQUOTE,
5478         ET_P,
5479         ET_BR,
5480         ET_A,
5481     };
5482
5483     hres = IHTMLDocument2_get_all(doc, &col);
5484     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5485     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5486     IHTMLElementCollection_Release(col);
5487
5488     range = test_create_body_range(doc);
5489     test_exec((IUnknown*)range, &CGID_MSHTML, IDM_INDENT, NULL, NULL);
5490     IHTMLTxtRange_Release(range);
5491
5492     hres = IHTMLDocument2_get_all(doc, &col);
5493     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5494     test_elem_collection((IUnknown*)col, indent_types, sizeof(indent_types)/sizeof(indent_types[0]));
5495     IHTMLElementCollection_Release(col);
5496 }
5497
5498 static void test_cond_comment(IHTMLDocument2 *doc)
5499 {
5500     IHTMLElementCollection *col;
5501     HRESULT hres;
5502
5503     static const elem_type_t all_types[] = {
5504         ET_HTML,
5505         ET_HEAD,
5506         ET_TITLE,
5507         ET_BODY,
5508         ET_BR
5509     };
5510
5511     hres = IHTMLDocument2_get_all(doc, &col);
5512     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5513     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5514     IHTMLElementCollection_Release(col);
5515 }
5516
5517 static IHTMLDocument2 *notif_doc;
5518 static BOOL doc_complete;
5519
5520 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
5521         REFIID riid, void**ppv)
5522 {
5523     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
5524         *ppv = iface;
5525         return S_OK;
5526     }
5527
5528     ok(0, "unexpected call\n");
5529     return E_NOINTERFACE;
5530 }
5531
5532 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
5533 {
5534     return 2;
5535 }
5536
5537 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
5538 {
5539     return 1;
5540 }
5541
5542 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
5543 {
5544     if(dispID == DISPID_READYSTATE){
5545         BSTR state;
5546         HRESULT hres;
5547
5548         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
5549         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
5550
5551         if(!strcmp_wa(state, "complete"))
5552             doc_complete = TRUE;
5553
5554         SysFreeString(state);
5555     }
5556
5557     return S_OK;
5558 }
5559
5560 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
5561 {
5562     ok(0, "unexpected call\n");
5563     return E_NOTIMPL;
5564 }
5565
5566 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
5567     PropertyNotifySink_QueryInterface,
5568     PropertyNotifySink_AddRef,
5569     PropertyNotifySink_Release,
5570     PropertyNotifySink_OnChanged,
5571     PropertyNotifySink_OnRequestEdit
5572 };
5573
5574 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
5575
5576 static IHTMLDocument2 *create_doc_with_string(const char *str)
5577 {
5578     IPersistStreamInit *init;
5579     IStream *stream;
5580     IHTMLDocument2 *doc;
5581     HGLOBAL mem;
5582     SIZE_T len;
5583
5584     notif_doc = doc = create_document();
5585     if(!doc)
5586         return NULL;
5587
5588     doc_complete = FALSE;
5589     len = strlen(str);
5590     mem = GlobalAlloc(0, len);
5591     memcpy(mem, str, len);
5592     CreateStreamOnHGlobal(mem, TRUE, &stream);
5593
5594     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
5595
5596     IPersistStreamInit_Load(init, stream);
5597     IPersistStreamInit_Release(init);
5598     IStream_Release(stream);
5599
5600     return doc;
5601 }
5602
5603 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
5604 {
5605     IConnectionPointContainer *container;
5606     IConnectionPoint *cp;
5607     DWORD cookie;
5608     HRESULT hres;
5609
5610     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
5611     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
5612
5613     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
5614     IConnectionPointContainer_Release(container);
5615     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
5616
5617     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
5618     IConnectionPoint_Release(cp);
5619     ok(hres == S_OK, "Advise failed: %08x\n", hres);
5620 }
5621
5622 typedef void (*domtest_t)(IHTMLDocument2*);
5623
5624 static void run_domtest(const char *str, domtest_t test)
5625 {
5626     IHTMLDocument2 *doc;
5627     IHTMLElement *body = NULL;
5628     ULONG ref;
5629     MSG msg;
5630     HRESULT hres;
5631
5632     doc = create_doc_with_string(str);
5633     if(!doc)
5634         return;
5635
5636     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
5637
5638     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
5639         TranslateMessage(&msg);
5640         DispatchMessage(&msg);
5641     }
5642
5643     hres = IHTMLDocument2_get_body(doc, &body);
5644     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5645
5646     if(body) {
5647         IHTMLElement_Release(body);
5648         test(doc);
5649     }else {
5650         skip("Could not get document body. Assuming no Gecko installed.\n");
5651     }
5652
5653     ref = IHTMLDocument2_Release(doc);
5654     ok(!ref ||
5655        ref == 1, /* Vista */
5656        "ref = %d\n", ref);
5657 }
5658
5659 static void gecko_installer_workaround(BOOL disable)
5660 {
5661     HKEY hkey;
5662     DWORD res;
5663
5664     static BOOL has_url = FALSE;
5665     static char url[2048];
5666
5667     if(!disable && !has_url)
5668         return;
5669
5670     res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
5671     if(res != ERROR_SUCCESS)
5672         return;
5673
5674     if(disable) {
5675         DWORD type, size = sizeof(url);
5676
5677         res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
5678         if(res == ERROR_SUCCESS && type == REG_SZ)
5679             has_url = TRUE;
5680
5681         RegDeleteValue(hkey, "GeckoUrl");
5682     }else {
5683         RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
5684     }
5685
5686     RegCloseKey(hkey);
5687 }
5688
5689 START_TEST(dom)
5690 {
5691     gecko_installer_workaround(TRUE);
5692     CoInitialize(NULL);
5693
5694     run_domtest(doc_str1, test_doc_elem);
5695     run_domtest(doc_str1, test_get_set_attr);
5696     run_domtest(range_test_str, test_txtrange);
5697     run_domtest(range_test2_str, test_txtrange2);
5698     if (winetest_interactive || ! is_ie_hardened()) {
5699         run_domtest(elem_test_str, test_elems);
5700     }else {
5701         skip("IE running in Enhanced Security Configuration\n");
5702     }
5703     run_domtest(doc_blank, test_create_elems);
5704     run_domtest(doc_blank, test_defaults);
5705     run_domtest(indent_test_str, test_indent);
5706     run_domtest(cond_comment_str, test_cond_comment);
5707
5708     CoUninitialize();
5709     gecko_installer_workaround(FALSE);
5710 }