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