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