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