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