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