rsaenh/tests: Fix memory leaks.
[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 IDispatchEx: %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     IDispatchEx *dispex;
3054     LONG l, exl;
3055     HDC hdc;
3056     HRESULT hres;
3057
3058     static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
3059
3060     screen = NULL;
3061     hres = IHTMLWindow2_get_screen(window, &screen);
3062     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
3063     ok(screen != NULL, "screen == NULL\n");
3064
3065     screen2 = NULL;
3066     hres = IHTMLWindow2_get_screen(window, &screen2);
3067     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
3068     ok(screen2 != NULL, "screen == NULL\n");
3069     ok(iface_cmp((IUnknown*)screen2, (IUnknown*)screen), "screen2 != screen\n");
3070     IHTMLScreen_Release(screen2);
3071
3072     hres = IHTMLScreen_QueryInterface(screen, &IID_IDispatchEx, (void**)&dispex);
3073     ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres);
3074     if(SUCCEEDED(hres)) {
3075         test_disp((IUnknown*)screen, &DIID_DispHTMLScreen, "[object]");
3076         IDispatchEx_Release(dispex);
3077     }
3078
3079     hdc = CreateICW(displayW, NULL, NULL, NULL);
3080
3081     exl = GetDeviceCaps(hdc, HORZRES);
3082     l = 0xdeadbeef;
3083     hres = IHTMLScreen_get_width(screen, &l);
3084     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3085     ok(l == exl, "width = %d, expected %d\n", l, exl);
3086
3087     exl = GetDeviceCaps(hdc, VERTRES);
3088     l = 0xdeadbeef;
3089     hres = IHTMLScreen_get_height(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     exl = GetDeviceCaps(hdc, BITSPIXEL);
3094     l = 0xdeadbeef;
3095     hres = IHTMLScreen_get_colorDepth(screen, &l);
3096     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3097     ok(l == exl, "height = %d, expected %d\n", l, exl);
3098
3099     DeleteObject(hdc);
3100
3101     IHTMLScreen_Release(screen);
3102 }
3103
3104 static void test_current_style(IHTMLCurrentStyle *current_style)
3105 {
3106     BSTR str;
3107     HRESULT hres;
3108     VARIANT v;
3109
3110     test_disp((IUnknown*)current_style, &DIID_DispHTMLCurrentStyle, "[object]");
3111     test_ifaces((IUnknown*)current_style, cstyle_iids);
3112
3113     hres = IHTMLCurrentStyle_get_display(current_style, &str);
3114     ok(hres == S_OK, "get_display failed: %08x\n", hres);
3115     ok(!strcmp_wa(str, "block"), "get_display returned %s\n", wine_dbgstr_w(str));
3116     SysFreeString(str);
3117
3118     hres = IHTMLCurrentStyle_get_position(current_style, &str);
3119     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3120     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
3121     SysFreeString(str);
3122
3123     hres = IHTMLCurrentStyle_get_fontFamily(current_style, &str);
3124     ok(hres == S_OK, "get_fontFamily failed: %08x\n", hres);
3125     SysFreeString(str);
3126
3127     hres = IHTMLCurrentStyle_get_fontStyle(current_style, &str);
3128     ok(hres == S_OK, "get_fontStyle failed: %08x\n", hres);
3129     ok(!strcmp_wa(str, "normal"), "get_fontStyle returned %s\n", wine_dbgstr_w(str));
3130     SysFreeString(str);
3131
3132     hres = IHTMLCurrentStyle_get_backgroundImage(current_style, &str);
3133     ok(hres == S_OK, "get_backgroundImage failed: %08x\n", hres);
3134     ok(!strcmp_wa(str, "none"), "get_backgroundImage returned %s\n", wine_dbgstr_w(str));
3135     SysFreeString(str);
3136
3137     hres = IHTMLCurrentStyle_get_fontVariant(current_style, &str);
3138     ok(hres == S_OK, "get_fontVariant failed: %08x\n", hres);
3139     ok(!strcmp_wa(str, "normal"), "get_fontVariant returned %s\n", wine_dbgstr_w(str));
3140     SysFreeString(str);
3141
3142     hres = IHTMLCurrentStyle_get_borderTopStyle(current_style, &str);
3143     ok(hres == S_OK, "get_borderTopStyle failed: %08x\n", hres);
3144     ok(!strcmp_wa(str, "none"), "get_borderTopStyle returned %s\n", wine_dbgstr_w(str));
3145     SysFreeString(str);
3146
3147     hres = IHTMLCurrentStyle_get_borderRightStyle(current_style, &str);
3148     ok(hres == S_OK, "get_borderRightStyle failed: %08x\n", hres);
3149     ok(!strcmp_wa(str, "none"), "get_borderRightStyle returned %s\n", wine_dbgstr_w(str));
3150     SysFreeString(str);
3151
3152     hres = IHTMLCurrentStyle_get_borderBottomStyle(current_style, &str);
3153     ok(hres == S_OK, "get_borderBottomStyle failed: %08x\n", hres);
3154     ok(!strcmp_wa(str, "none"), "get_borderBottomStyle returned %s\n", wine_dbgstr_w(str));
3155     SysFreeString(str);
3156
3157     hres = IHTMLCurrentStyle_get_borderLeftStyle(current_style, &str);
3158     ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres);
3159     ok(!strcmp_wa(str, "none"), "get_borderLeftStyle returned %s\n", wine_dbgstr_w(str));
3160     SysFreeString(str);
3161
3162     hres = IHTMLCurrentStyle_get_textAlign(current_style, &str);
3163     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
3164     ok(!strcmp_wa(str, "center"), "get_textAlign returned %s\n", wine_dbgstr_w(str));
3165     SysFreeString(str);
3166
3167     hres = IHTMLCurrentStyle_get_textDecoration(current_style, &str);
3168     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3169     ok(!strcmp_wa(str, "none"), "get_textDecoration returned %s\n", wine_dbgstr_w(str));
3170     SysFreeString(str);
3171
3172     hres = IHTMLCurrentStyle_get_cursor(current_style, &str);
3173     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3174     ok(!strcmp_wa(str, "default"), "get_cursor returned %s\n", wine_dbgstr_w(str));
3175     SysFreeString(str);
3176
3177     hres = IHTMLCurrentStyle_get_backgroundRepeat(current_style, &str);
3178     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
3179     ok(!strcmp_wa(str, "repeat"), "get_backgroundRepeat returned %s\n", wine_dbgstr_w(str));
3180     SysFreeString(str);
3181
3182     hres = IHTMLCurrentStyle_get_borderColor(current_style, &str);
3183     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
3184     SysFreeString(str);
3185
3186     hres = IHTMLCurrentStyle_get_borderStyle(current_style, &str);
3187     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
3188     SysFreeString(str);
3189
3190     hres = IHTMLCurrentStyle_get_visibility(current_style, &str);
3191     ok(hres == S_OK, "get_visibility failed: %08x\n", hres);
3192     SysFreeString(str);
3193
3194     hres = IHTMLCurrentStyle_get_overflow(current_style, &str);
3195     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
3196     SysFreeString(str);
3197
3198     hres = IHTMLCurrentStyle_get_borderWidth(current_style, &str);
3199     ok(hres == S_OK, "get_borderWidth failed: %08x\n", hres);
3200     SysFreeString(str);
3201
3202     hres = IHTMLCurrentStyle_get_margin(current_style, &str);
3203     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3204     SysFreeString(str);
3205
3206     hres = IHTMLCurrentStyle_get_fontWeight(current_style, &v);
3207     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3208     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
3209     ok( V_I4(&v) == 400, "expect 400 got (%d)\n", V_I4(&v));
3210     VariantClear(&v);
3211
3212     hres = IHTMLCurrentStyle_get_fontSize(current_style, &v);
3213     ok(hres == S_OK, "get_fontSize failed: %08x\n", hres);
3214     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3215     VariantClear(&v);
3216
3217     hres = IHTMLCurrentStyle_get_left(current_style, &v);
3218     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3219     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3220     VariantClear(&v);
3221
3222     hres = IHTMLCurrentStyle_get_top(current_style, &v);
3223     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3224     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3225     VariantClear(&v);
3226
3227     hres = IHTMLCurrentStyle_get_width(current_style, &v);
3228     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3229     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3230     VariantClear(&v);
3231
3232     hres = IHTMLCurrentStyle_get_height(current_style, &v);
3233     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3234     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3235     VariantClear(&v);
3236
3237     hres = IHTMLCurrentStyle_get_paddingLeft(current_style, &v);
3238     ok(hres == S_OK, "get_paddingLeft failed: %08x\n", hres);
3239     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3240     VariantClear(&v);
3241
3242     hres = IHTMLCurrentStyle_get_zIndex(current_style, &v);
3243     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
3244     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
3245     ok( V_I4(&v) == 1, "expect 1 got (%d)\n", V_I4(&v));
3246     VariantClear(&v);
3247
3248     hres = IHTMLCurrentStyle_get_verticalAlign(current_style, &v);
3249     ok(hres == S_OK, "get_verticalAlign failed: %08x\n", hres);
3250     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3251     ok(!strcmp_wa(V_BSTR(&v), "middle"), "get_verticalAlign returned %s\n", wine_dbgstr_w(V_BSTR(&v)));
3252     VariantClear(&v);
3253
3254     hres = IHTMLCurrentStyle_get_marginRight(current_style, &v);
3255     ok(hres == S_OK, "get_marginRight failed: %08x\n", hres);
3256     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3257     VariantClear(&v);
3258
3259     hres = IHTMLCurrentStyle_get_marginLeft(current_style, &v);
3260     ok(hres == S_OK, "get_marginLeft failed: %08x\n", hres);
3261     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3262     VariantClear(&v);
3263
3264     hres = IHTMLCurrentStyle_get_borderLeftWidth(current_style, &v);
3265     ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres);
3266     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3267     VariantClear(&v);
3268
3269     V_BSTR(&v) = NULL;
3270     hres = IHTMLCurrentStyle_get_borderRightWidth(current_style, &v);
3271     ok(hres == S_OK, "get_borderRightWidth failed: %08x\n", hres);
3272     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3273     VariantClear(&v);
3274
3275     hres = IHTMLCurrentStyle_get_borderBottomWidth(current_style, &v);
3276     ok(hres == S_OK, "get_borderBottomWidth failed: %08x\n", hres);
3277     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3278     VariantClear(&v);
3279
3280     hres = IHTMLCurrentStyle_get_borderTopWidth(current_style, &v);
3281     ok(hres == S_OK, "get_borderTopWidth failed: %08x\n", hres);
3282     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3283     VariantClear(&v);
3284
3285     hres = IHTMLCurrentStyle_get_color(current_style, &v);
3286     ok(hres == S_OK, "get_color failed: %08x\n", hres);
3287     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3288     VariantClear(&v);
3289
3290     hres = IHTMLCurrentStyle_get_backgroundColor(current_style, &v);
3291     ok(hres == S_OK, "get_backgroundColor failed: %08x\n", hres);
3292     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3293     VariantClear(&v);
3294
3295     hres = IHTMLCurrentStyle_get_borderLeftColor(current_style, &v);
3296     ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres);
3297     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3298     VariantClear(&v);
3299
3300     hres = IHTMLCurrentStyle_get_borderTopColor(current_style, &v);
3301     ok(hres == S_OK, "get_borderTopColor failed: %08x\n", hres);
3302     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3303     VariantClear(&v);
3304
3305     hres = IHTMLCurrentStyle_get_borderRightColor(current_style, &v);
3306     ok(hres == S_OK, "get_borderRightColor failed: %08x\n", hres);
3307     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3308     VariantClear(&v);
3309
3310     hres = IHTMLCurrentStyle_get_borderBottomColor(current_style, &v);
3311     ok(hres == S_OK, "get_borderBottomColor failed: %08x\n", hres);
3312     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3313     VariantClear(&v);
3314
3315     hres = IHTMLCurrentStyle_get_paddingTop(current_style, &v);
3316     ok(hres == S_OK, "get_paddingTop failed: %08x\n", hres);
3317     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3318     VariantClear(&v);
3319
3320     hres = IHTMLCurrentStyle_get_paddingRight(current_style, &v);
3321     ok(hres == S_OK, "get_paddingRight failed: %08x\n", hres);
3322     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3323     VariantClear(&v);
3324
3325     hres = IHTMLCurrentStyle_get_paddingBottom(current_style, &v);
3326     ok(hres == S_OK, "get_paddingRight failed: %08x\n", hres);
3327     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3328     VariantClear(&v);
3329
3330     hres = IHTMLCurrentStyle_get_letterSpacing(current_style, &v);
3331     ok(hres == S_OK, "get_letterSpacing failed: %08x\n", hres);
3332     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3333     VariantClear(&v);
3334
3335     hres = IHTMLCurrentStyle_get_marginTop(current_style, &v);
3336     ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
3337     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3338     VariantClear(&v);
3339
3340     hres = IHTMLCurrentStyle_get_marginBottom(current_style, &v);
3341     ok(hres == S_OK, "get_marginBottom failed: %08x\n", hres);
3342     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3343     VariantClear(&v);
3344
3345     hres = IHTMLCurrentStyle_get_right(current_style, &v);
3346     ok(hres == S_OK, "get_Right failed: %08x\n", hres);
3347     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3348     VariantClear(&v);
3349
3350     hres = IHTMLCurrentStyle_get_bottom(current_style, &v);
3351     ok(hres == S_OK, "get_bottom failed: %08x\n", hres);
3352     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3353     VariantClear(&v);
3354
3355     hres = IHTMLCurrentStyle_get_lineHeight(current_style, &v);
3356     ok(hres == S_OK, "get_lineHeight failed: %08x\n", hres);
3357     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3358     VariantClear(&v);
3359
3360     hres = IHTMLCurrentStyle_get_textIndent(current_style, &v);
3361     ok(hres == S_OK, "get_textIndent failed: %08x\n", hres);
3362     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3363     VariantClear(&v);
3364 }
3365
3366 static void test_style2(IHTMLStyle2 *style2)
3367 {
3368     BSTR str;
3369     HRESULT hres;
3370
3371     str = (void*)0xdeadbeef;
3372     hres = IHTMLStyle2_get_position(style2, &str);
3373     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3374     ok(!str, "str != NULL\n");
3375
3376     str = a2bstr("absolute");
3377     hres = IHTMLStyle2_put_position(style2, str);
3378     ok(hres == S_OK, "put_position failed: %08x\n", hres);
3379     SysFreeString(str);
3380
3381     str = NULL;
3382     hres = IHTMLStyle2_get_position(style2, &str);
3383     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3384     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
3385     SysFreeString(str);
3386 }
3387
3388 static void test_style3(IHTMLStyle3 *style3)
3389 {
3390     BSTR str;
3391     HRESULT hres;
3392
3393     str = (void*)0xdeadbeef;
3394     hres = IHTMLStyle3_get_wordWrap(style3, &str);
3395     ok(hres == S_OK, "get_wordWrap failed: %08x\n", hres);
3396     ok(!str, "str != NULL\n");
3397
3398     str = a2bstr("break-word");
3399     hres = IHTMLStyle3_put_wordWrap(style3, str);
3400     ok(hres == S_OK, "put_wordWrap failed: %08x\n", hres);
3401     SysFreeString(str);
3402
3403     str = NULL;
3404     hres = IHTMLStyle3_get_wordWrap(style3, &str);
3405     ok(hres == S_OK, "get_wordWrap failed: %08x\n", hres);
3406     ok(!strcmp_wa(str, "break-word"), "get_wordWrap returned %s\n", wine_dbgstr_w(str));
3407     SysFreeString(str);
3408 }
3409
3410 static void test_style4(IHTMLStyle4 *style4)
3411 {
3412     HRESULT hres;
3413     VARIANT v;
3414     VARIANT vdefault;
3415
3416     hres = IHTMLStyle4_get_minHeight(style4, &vdefault);
3417     ok(hres == S_OK, "get_minHeight failed: %08x\n", hres);
3418
3419     V_VT(&v) = VT_BSTR;
3420     V_BSTR(&v) = a2bstr("10px");
3421     hres = IHTMLStyle4_put_minHeight(style4, v);
3422     ok(hres == S_OK, "put_minHeight failed: %08x\n", hres);
3423     VariantClear(&v);
3424
3425     hres = IHTMLStyle4_get_minHeight(style4, &v);
3426     ok(hres == S_OK, "get_minHeight failed: %08x\n", hres);
3427     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3428     ok( !strcmp_wa(V_BSTR(&v), "10px"), "expect 10px got (%s)\n", wine_dbgstr_w(V_BSTR(&v)));
3429
3430     hres = IHTMLStyle4_put_minHeight(style4, vdefault);
3431     ok(hres == S_OK, "put_minHeight failed: %08x\n", hres);
3432     VariantClear(&vdefault);
3433 }
3434
3435 static void test_default_style(IHTMLStyle *style)
3436 {
3437     IHTMLStyle2 *style2;
3438     IHTMLStyle3 *style3;
3439     IHTMLStyle4 *style4;
3440     VARIANT_BOOL b;
3441     VARIANT v;
3442     BSTR str;
3443     HRESULT hres;
3444     float f;
3445     BSTR sOverflowDefault;
3446     BSTR sDefault;
3447     VARIANT vDefault;
3448
3449     test_disp((IUnknown*)style, &DIID_DispHTMLStyle, "[object]");
3450     test_ifaces((IUnknown*)style, style_iids);
3451
3452     test_style_csstext(style, NULL);
3453
3454     hres = IHTMLStyle_get_position(style, &str);
3455     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3456     ok(!str, "str=%s\n", wine_dbgstr_w(str));
3457
3458     V_VT(&v) = VT_NULL;
3459     hres = IHTMLStyle_get_marginRight(style, &v);
3460     ok(hres == S_OK, "get_marginRight failed: %08x\n", hres);
3461     ok(V_VT(&v) == VT_BSTR, "V_VT(marginRight) = %d\n", V_VT(&v));
3462     ok(!V_BSTR(&v), "V_BSTR(marginRight) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3463
3464     V_VT(&v) = VT_NULL;
3465     hres = IHTMLStyle_get_marginLeft(style, &v);
3466     ok(hres == S_OK, "get_marginLeft failed: %08x\n", hres);
3467     ok(V_VT(&v) == VT_BSTR, "V_VT(marginLeft) = %d\n", V_VT(&v));
3468     ok(!V_BSTR(&v), "V_BSTR(marginLeft) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3469
3470     str = (void*)0xdeadbeef;
3471     hres = IHTMLStyle_get_fontFamily(style, &str);
3472     ok(hres == S_OK, "get_fontFamily failed: %08x\n", hres);
3473     ok(!str, "fontFamily = %s\n", wine_dbgstr_w(str));
3474
3475     str = (void*)0xdeadbeef;
3476     hres = IHTMLStyle_get_fontWeight(style, &str);
3477     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3478     ok(!str, "fontWeight = %s\n", wine_dbgstr_w(str));
3479
3480     hres = IHTMLStyle_get_fontWeight(style, &sDefault);
3481     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3482
3483     str = a2bstr("test");
3484     hres = IHTMLStyle_put_fontWeight(style, str);
3485     ok(hres == E_INVALIDARG, "put_fontWeight failed: %08x\n", hres);
3486     SysFreeString(str);
3487
3488     str = a2bstr("bold");
3489     hres = IHTMLStyle_put_fontWeight(style, str);
3490     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3491     SysFreeString(str);
3492
3493     str = a2bstr("bolder");
3494     hres = IHTMLStyle_put_fontWeight(style, str);
3495     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3496     SysFreeString(str);
3497
3498     str = a2bstr("lighter");
3499     hres = IHTMLStyle_put_fontWeight(style, str);
3500     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3501     SysFreeString(str);
3502
3503     str = a2bstr("100");
3504     hres = IHTMLStyle_put_fontWeight(style, str);
3505     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3506     SysFreeString(str);
3507
3508     str = a2bstr("200");
3509     hres = IHTMLStyle_put_fontWeight(style, str);
3510     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3511     SysFreeString(str);
3512
3513     str = a2bstr("300");
3514     hres = IHTMLStyle_put_fontWeight(style, str);
3515     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3516     SysFreeString(str);
3517
3518     str = a2bstr("400");
3519     hres = IHTMLStyle_put_fontWeight(style, str);
3520     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3521     SysFreeString(str);
3522
3523     str = a2bstr("500");
3524     hres = IHTMLStyle_put_fontWeight(style, str);
3525     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3526     SysFreeString(str);
3527
3528     str = a2bstr("600");
3529     hres = IHTMLStyle_put_fontWeight(style, str);
3530     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3531     SysFreeString(str);
3532
3533     str = a2bstr("700");
3534     hres = IHTMLStyle_put_fontWeight(style, str);
3535     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3536     SysFreeString(str);
3537
3538     str = a2bstr("800");
3539     hres = IHTMLStyle_put_fontWeight(style, str);
3540     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3541     SysFreeString(str);
3542
3543     str = a2bstr("900");
3544     hres = IHTMLStyle_put_fontWeight(style, str);
3545     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3546     SysFreeString(str);
3547
3548     hres = IHTMLStyle_get_fontWeight(style, &str);
3549     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3550     ok(!strcmp_wa(str, "900"), "str != style900\n");
3551     SysFreeString(str);
3552
3553     hres = IHTMLStyle_put_fontWeight(style, sDefault);
3554     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3555     SysFreeString(sDefault);
3556
3557     /* font Variant */
3558     hres = IHTMLStyle_get_fontVariant(style, NULL);
3559     ok(hres == E_INVALIDARG, "get_fontVariant failed: %08x\n", hres);
3560
3561     hres = IHTMLStyle_get_fontVariant(style, &sDefault);
3562     ok(hres == S_OK, "get_fontVariant failed: %08x\n", hres);
3563
3564     str = a2bstr("test");
3565     hres = IHTMLStyle_put_fontVariant(style, str);
3566     ok(hres == E_INVALIDARG, "fontVariant failed: %08x\n", hres);
3567     SysFreeString(str);
3568
3569     str = a2bstr("small-caps");
3570     hres = IHTMLStyle_put_fontVariant(style, str);
3571     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3572     SysFreeString(str);
3573
3574     str = a2bstr("normal");
3575     hres = IHTMLStyle_put_fontVariant(style, str);
3576     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3577     SysFreeString(str);
3578
3579     hres = IHTMLStyle_put_fontVariant(style, sDefault);
3580     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3581     SysFreeString(sDefault);
3582
3583     str = (void*)0xdeadbeef;
3584     hres = IHTMLStyle_get_display(style, &str);
3585     ok(hres == S_OK, "get_display failed: %08x\n", hres);
3586     ok(!str, "display = %s\n", wine_dbgstr_w(str));
3587
3588     str = (void*)0xdeadbeef;
3589     hres = IHTMLStyle_get_visibility(style, &str);
3590     ok(hres == S_OK, "get_visibility failed: %08x\n", hres);
3591     ok(!str, "visibility = %s\n", wine_dbgstr_w(str));
3592
3593     V_VT(&v) = VT_NULL;
3594     hres = IHTMLStyle_get_fontSize(style, &v);
3595     ok(hres == S_OK, "get_fontSize failed: %08x\n", hres);
3596     ok(V_VT(&v) == VT_BSTR, "V_VT(fontSize) = %d\n", V_VT(&v));
3597     ok(!V_BSTR(&v), "V_BSTR(fontSize) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3598
3599     V_VT(&v) = VT_NULL;
3600     hres = IHTMLStyle_get_color(style, &v);
3601     ok(hres == S_OK, "get_color failed: %08x\n", hres);
3602     ok(V_VT(&v) == VT_BSTR, "V_VT(color) = %d\n", V_VT(&v));
3603     ok(!V_BSTR(&v), "V_BSTR(color) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3604
3605     b = 0xfefe;
3606     hres = IHTMLStyle_get_textDecorationUnderline(style, &b);
3607     ok(hres == S_OK, "get_textDecorationUnderline failed: %08x\n", hres);
3608     ok(b == VARIANT_FALSE, "textDecorationUnderline = %x\n", b);
3609
3610     hres = IHTMLStyle_put_textDecorationUnderline(style, VARIANT_TRUE);
3611     ok(hres == S_OK, "put_textDecorationUnderline failed: %08x\n", hres);
3612     ok(b == VARIANT_FALSE, "textDecorationUnderline = %x\n", b);
3613
3614     hres = IHTMLStyle_get_textDecorationUnderline(style, &b);
3615     ok(hres == S_OK, "get_textDecorationUnderline failed: %08x\n", hres);
3616     ok(b == VARIANT_TRUE, "textDecorationUnderline = %x\n", b);
3617
3618     hres = IHTMLStyle_put_textDecorationUnderline(style, VARIANT_FALSE);
3619     ok(hres == S_OK, "put_textDecorationUnderline failed: %08x\n", hres);
3620
3621     b = 0xfefe;
3622     hres = IHTMLStyle_get_textDecorationLineThrough(style, &b);
3623     ok(hres == S_OK, "get_textDecorationLineThrough failed: %08x\n", hres);
3624     ok(b == VARIANT_FALSE, "textDecorationLineThrough = %x\n", b);
3625
3626     hres = IHTMLStyle_put_textDecorationLineThrough(style, VARIANT_TRUE);
3627     ok(hres == S_OK, "put_textDecorationLineThrough failed: %08x\n", hres);
3628     ok(b == VARIANT_FALSE, "textDecorationLineThrough = %x\n", b);
3629
3630     hres = IHTMLStyle_get_textDecorationLineThrough(style, &b);
3631     ok(hres == S_OK, "get_textDecorationLineThrough failed: %08x\n", hres);
3632     ok(b == VARIANT_TRUE, "textDecorationLineThrough = %x\n", b);
3633
3634     hres = IHTMLStyle_put_textDecorationLineThrough(style, VARIANT_FALSE);
3635     ok(hres == S_OK, "put_textDecorationLineThrough failed: %08x\n", hres);
3636
3637     b = 0xfefe;
3638     hres = IHTMLStyle_get_textDecorationNone(style, &b);
3639     ok(hres == S_OK, "get_textDecorationNone failed: %08x\n", hres);
3640     ok(b == VARIANT_FALSE, "textDecorationNone = %x\n", b);
3641
3642     hres = IHTMLStyle_put_textDecorationNone(style, VARIANT_TRUE);
3643     ok(hres == S_OK, "put_textDecorationNone failed: %08x\n", hres);
3644     ok(b == VARIANT_FALSE, "textDecorationNone = %x\n", b);
3645
3646     hres = IHTMLStyle_get_textDecorationNone(style, &b);
3647     ok(hres == S_OK, "get_textDecorationNone failed: %08x\n", hres);
3648     ok(b == VARIANT_TRUE, "textDecorationNone = %x\n", b);
3649
3650     hres = IHTMLStyle_put_textDecorationNone(style, VARIANT_FALSE);
3651     ok(hres == S_OK, "put_textDecorationNone failed: %08x\n", hres);
3652
3653     b = 0xfefe;
3654     hres = IHTMLStyle_get_textDecorationOverline(style, &b);
3655     ok(hres == S_OK, "get_textDecorationOverline failed: %08x\n", hres);
3656     ok(b == VARIANT_FALSE, "textDecorationOverline = %x\n", b);
3657
3658     hres = IHTMLStyle_put_textDecorationOverline(style, VARIANT_TRUE);
3659     ok(hres == S_OK, "put_textDecorationOverline failed: %08x\n", hres);
3660     ok(b == VARIANT_FALSE, "textDecorationOverline = %x\n", b);
3661
3662     hres = IHTMLStyle_get_textDecorationOverline(style, &b);
3663     ok(hres == S_OK, "get_textDecorationOverline failed: %08x\n", hres);
3664     ok(b == VARIANT_TRUE, "textDecorationOverline = %x\n", b);
3665
3666     hres = IHTMLStyle_put_textDecorationOverline(style, VARIANT_FALSE);
3667     ok(hres == S_OK, "put_textDecorationOverline failed: %08x\n", hres);
3668
3669     b = 0xfefe;
3670     hres = IHTMLStyle_get_textDecorationBlink(style, &b);
3671     ok(hres == S_OK, "get_textDecorationBlink failed: %08x\n", hres);
3672     ok(b == VARIANT_FALSE, "textDecorationBlink = %x\n", b);
3673
3674     hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_TRUE);
3675     ok(hres == S_OK, "put_textDecorationBlink failed: %08x\n", hres);
3676     ok(b == VARIANT_FALSE, "textDecorationBlink = %x\n", b);
3677
3678     hres = IHTMLStyle_get_textDecorationBlink(style, &b);
3679     ok(hres == S_OK, "get_textDecorationBlink failed: %08x\n", hres);
3680     ok(b == VARIANT_TRUE, "textDecorationBlink = %x\n", b);
3681
3682     hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_FALSE);
3683     ok(hres == S_OK, "textDecorationBlink failed: %08x\n", hres);
3684
3685     hres = IHTMLStyle_get_textDecoration(style, &sDefault);
3686     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3687
3688     str = a2bstr("invalid");
3689     hres = IHTMLStyle_put_textDecoration(style, str);
3690     ok(hres == E_INVALIDARG, "put_textDecoration failed: %08x\n", hres);
3691     SysFreeString(str);
3692
3693     str = a2bstr("none");
3694     hres = IHTMLStyle_put_textDecoration(style, str);
3695     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3696     SysFreeString(str);
3697
3698     str = a2bstr("underline");
3699     hres = IHTMLStyle_put_textDecoration(style, str);
3700     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3701     SysFreeString(str);
3702
3703     str = a2bstr("overline");
3704     hres = IHTMLStyle_put_textDecoration(style, str);
3705     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3706     SysFreeString(str);
3707
3708     str = a2bstr("line-through");
3709     hres = IHTMLStyle_put_textDecoration(style, str);
3710     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3711     SysFreeString(str);
3712
3713     str = a2bstr("blink");
3714     hres = IHTMLStyle_put_textDecoration(style, str);
3715     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3716     SysFreeString(str);
3717
3718     hres = IHTMLStyle_get_textDecoration(style, &str);
3719     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3720     ok(!strcmp_wa(str, "blink"), "str != blink\n");
3721     SysFreeString(str);
3722
3723     hres = IHTMLStyle_put_textDecoration(style, sDefault);
3724     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3725     SysFreeString(sDefault);
3726
3727     hres = IHTMLStyle_get_posWidth(style, NULL);
3728     ok(hres == E_POINTER, "get_posWidth failed: %08x\n", hres);
3729
3730     hres = IHTMLStyle_get_posWidth(style, &f);
3731     ok(hres == S_OK, "get_posWidth failed: %08x\n", hres);
3732     ok(f == 0.0f, "f = %f\n", f);
3733
3734     V_VT(&v) = VT_EMPTY;
3735     hres = IHTMLStyle_get_width(style, &v);
3736     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3737     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3738     ok(!V_BSTR(&v), "V_BSTR(v)=%p\n", V_BSTR(&v));
3739
3740     hres = IHTMLStyle_put_posWidth(style, 2.2);
3741     ok(hres == S_OK, "put_posWidth failed: %08x\n", hres);
3742
3743     hres = IHTMLStyle_get_posWidth(style, &f);
3744     ok(hres == S_OK, "get_posWidth failed: %08x\n", hres);
3745     ok(f == 2.0f ||
3746        f == 2.2f, /* IE8 */
3747        "f = %f\n", f);
3748
3749     V_VT(&v) = VT_BSTR;
3750     V_BSTR(&v) = a2bstr("auto");
3751     hres = IHTMLStyle_put_width(style, v);
3752     ok(hres == S_OK, "put_width failed: %08x\n", hres);
3753     VariantClear(&v);
3754
3755     V_VT(&v) = VT_EMPTY;
3756     hres = IHTMLStyle_get_width(style, &v);
3757     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3758     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3759     ok(!strcmp_wa(V_BSTR(&v), "auto"), "V_BSTR(v)=%s\n", wine_dbgstr_w(V_BSTR(&v)));
3760     VariantClear(&v);
3761
3762     /* margin tests */
3763     str = (void*)0xdeadbeef;
3764     hres = IHTMLStyle_get_margin(style, &str);
3765     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3766     ok(!str, "margin = %s\n", wine_dbgstr_w(str));
3767
3768     str = a2bstr("1");
3769     hres = IHTMLStyle_put_margin(style, str);
3770     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
3771     SysFreeString(str);
3772
3773     hres = IHTMLStyle_get_margin(style, &str);
3774     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3775     ok(!strcmp_wa(str, "1px"), "margin = %s\n", wine_dbgstr_w(str));
3776
3777     hres = IHTMLStyle_put_margin(style, NULL);
3778     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
3779
3780     str = NULL;
3781     hres = IHTMLStyle_get_border(style, &str);
3782     ok(hres == S_OK, "get_border failed: %08x\n", hres);
3783     ok(!str || !*str, "str is not empty\n");
3784     SysFreeString(str);
3785
3786     str = a2bstr("1px");
3787     hres = IHTMLStyle_put_border(style, str);
3788     ok(hres == S_OK, "put_border failed: %08x\n", hres);
3789     SysFreeString(str);
3790
3791     V_VT(&v) = VT_EMPTY;
3792     hres = IHTMLStyle_get_left(style, &v);
3793     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3794     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3795     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3796     VariantClear(&v);
3797
3798     /* Test posLeft */
3799     hres = IHTMLStyle_get_posLeft(style, NULL);
3800     ok(hres == E_POINTER, "get_posLeft failed: %08x\n", hres);
3801
3802     f = 1.0f;
3803     hres = IHTMLStyle_get_posLeft(style, &f);
3804     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3805     ok(f == 0.0, "expected 0.0 got %f\n", f);
3806
3807     hres = IHTMLStyle_put_posLeft(style, 4.9f);
3808     ok(hres == S_OK, "put_posLeft failed: %08x\n", hres);
3809
3810     hres = IHTMLStyle_get_posLeft(style, &f);
3811     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3812     ok(f == 4.0 ||
3813        f == 4.9f, /* IE8 */
3814        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3815
3816     /* Ensure left is updated correctly. */
3817     V_VT(&v) = VT_EMPTY;
3818     hres = IHTMLStyle_get_left(style, &v);
3819     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3820     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3821     ok(!strcmp_wa(V_BSTR(&v), "4px") ||
3822        !strcmp_wa(V_BSTR(&v), "4.9px"), /* IE8 */
3823        "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3824     VariantClear(&v);
3825
3826     /* Test left */
3827     V_VT(&v) = VT_BSTR;
3828     V_BSTR(&v) = a2bstr("3px");
3829     hres = IHTMLStyle_put_left(style, v);
3830     ok(hres == S_OK, "put_left failed: %08x\n", hres);
3831     VariantClear(&v);
3832
3833     hres = IHTMLStyle_get_posLeft(style, &f);
3834     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3835     ok(f == 3.0, "expected 3.0 got %f\n", f);
3836
3837     V_VT(&v) = VT_EMPTY;
3838     hres = IHTMLStyle_get_left(style, &v);
3839     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3840     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3841     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3842     VariantClear(&v);
3843
3844     V_VT(&v) = VT_NULL;
3845     hres = IHTMLStyle_put_left(style, v);
3846     ok(hres == S_OK, "put_left failed: %08x\n", hres);
3847
3848     V_VT(&v) = VT_EMPTY;
3849     hres = IHTMLStyle_get_left(style, &v);
3850     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3851     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3852     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3853     VariantClear(&v);
3854
3855     V_VT(&v) = VT_EMPTY;
3856     hres = IHTMLStyle_get_top(style, &v);
3857     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3858     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3859     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3860     VariantClear(&v);
3861
3862     /* Test posTop */
3863     hres = IHTMLStyle_get_posTop(style, NULL);
3864     ok(hres == E_POINTER, "get_posTop failed: %08x\n", hres);
3865
3866     f = 1.0f;
3867     hres = IHTMLStyle_get_posTop(style, &f);
3868     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3869     ok(f == 0.0, "expected 0.0 got %f\n", f);
3870
3871     hres = IHTMLStyle_put_posTop(style, 4.9f);
3872     ok(hres == S_OK, "put_posTop failed: %08x\n", hres);
3873
3874     hres = IHTMLStyle_get_posTop(style, &f);
3875     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3876     ok(f == 4.0 ||
3877        f == 4.9f, /* IE8 */
3878        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3879
3880     V_VT(&v) = VT_BSTR;
3881     V_BSTR(&v) = a2bstr("3px");
3882     hres = IHTMLStyle_put_top(style, v);
3883     ok(hres == S_OK, "put_top failed: %08x\n", hres);
3884     VariantClear(&v);
3885
3886     V_VT(&v) = VT_EMPTY;
3887     hres = IHTMLStyle_get_top(style, &v);
3888     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3889     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3890     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3891     VariantClear(&v);
3892
3893     hres = IHTMLStyle_get_posTop(style, &f);
3894     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3895     ok(f == 3.0, "expected 3.0 got %f\n", f);
3896
3897     V_VT(&v) = VT_NULL;
3898     hres = IHTMLStyle_put_top(style, v);
3899     ok(hres == S_OK, "put_top failed: %08x\n", hres);
3900
3901     V_VT(&v) = VT_EMPTY;
3902     hres = IHTMLStyle_get_top(style, &v);
3903     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3904     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3905     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3906     VariantClear(&v);
3907
3908     /* Test posHeight */
3909     hres = IHTMLStyle_get_posHeight(style, NULL);
3910     ok(hres == E_POINTER, "get_posHeight failed: %08x\n", hres);
3911
3912     V_VT(&v) = VT_EMPTY;
3913     hres = IHTMLStyle_get_height(style, &v);
3914     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3915     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3916     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3917     VariantClear(&v);
3918
3919     f = 1.0f;
3920     hres = IHTMLStyle_get_posHeight(style, &f);
3921     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
3922     ok(f == 0.0, "expected 0.0 got %f\n", f);
3923
3924     hres = IHTMLStyle_put_posHeight(style, 4.9f);
3925     ok(hres == S_OK, "put_posHeight failed: %08x\n", hres);
3926
3927     hres = IHTMLStyle_get_posHeight(style, &f);
3928     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
3929     ok(f == 4.0 ||
3930        f == 4.9f, /* IE8 */
3931        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3932
3933     V_VT(&v) = VT_BSTR;
3934     V_BSTR(&v) = a2bstr("64px");
3935     hres = IHTMLStyle_put_height(style, v);
3936     ok(hres == S_OK, "put_height failed: %08x\n", hres);
3937     VariantClear(&v);
3938
3939     V_VT(&v) = VT_EMPTY;
3940     hres = IHTMLStyle_get_height(style, &v);
3941     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3942     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3943     ok(!strcmp_wa(V_BSTR(&v), "64px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3944     VariantClear(&v);
3945
3946     hres = IHTMLStyle_get_posHeight(style, &f);
3947     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
3948     ok(f == 64.0, "expected 64.0 got %f\n", f);
3949
3950     str = (void*)0xdeadbeef;
3951     hres = IHTMLStyle_get_cursor(style, &str);
3952     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3953     ok(!str, "get_cursor != NULL\n");
3954     SysFreeString(str);
3955
3956     str = a2bstr("default");
3957     hres = IHTMLStyle_put_cursor(style, str);
3958     ok(hres == S_OK, "put_cursor failed: %08x\n", hres);
3959     SysFreeString(str);
3960
3961     str = NULL;
3962     hres = IHTMLStyle_get_cursor(style, &str);
3963     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3964     ok(!strcmp_wa(str, "default"), "get_cursor returned %s\n", wine_dbgstr_w(str));
3965     SysFreeString(str);
3966
3967     V_VT(&v) = VT_EMPTY;
3968     hres = IHTMLStyle_get_verticalAlign(style, &v);
3969     ok(hres == S_OK, "get_vertivalAlign failed: %08x\n", hres);
3970     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3971     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3972     VariantClear(&v);
3973
3974     V_VT(&v) = VT_BSTR;
3975     V_BSTR(&v) = a2bstr("middle");
3976     hres = IHTMLStyle_put_verticalAlign(style, v);
3977     ok(hres == S_OK, "put_vertivalAlign failed: %08x\n", hres);
3978     VariantClear(&v);
3979
3980     V_VT(&v) = VT_EMPTY;
3981     hres = IHTMLStyle_get_verticalAlign(style, &v);
3982     ok(hres == S_OK, "get_verticalAlign failed: %08x\n", hres);
3983     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3984     ok(!strcmp_wa(V_BSTR(&v), "middle"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3985     VariantClear(&v);
3986
3987     str = (void*)0xdeadbeef;
3988     hres = IHTMLStyle_get_textAlign(style, &str);
3989     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
3990     ok(!str, "textAlign != NULL\n");
3991
3992     str = a2bstr("center");
3993     hres = IHTMLStyle_put_textAlign(style, str);
3994     ok(hres == S_OK, "put_textAlign failed: %08x\n", hres);
3995     SysFreeString(str);
3996
3997     str = NULL;
3998     hres = IHTMLStyle_get_textAlign(style, &str);
3999     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
4000     ok(!strcmp_wa(str, "center"), "textAlign = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4001     SysFreeString(str);
4002
4003     str = (void*)0xdeadbeef;
4004     hres = IHTMLStyle_get_filter(style, &str);
4005     ok(hres == S_OK, "get_filter failed: %08x\n", hres);
4006     ok(!str, "filter != NULL\n");
4007
4008     str = a2bstr("alpha(opacity=100)");
4009     hres = IHTMLStyle_put_filter(style, str);
4010     ok(hres == S_OK, "put_filter failed: %08x\n", hres);
4011     SysFreeString(str);
4012
4013     V_VT(&v) = VT_EMPTY;
4014     hres = IHTMLStyle_get_zIndex(style, &v);
4015     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
4016     ok(V_VT(&v) == VT_I4, "V_VT(v)=%d\n", V_VT(&v));
4017     ok(!V_I4(&v), "V_I4(v) != 0\n");
4018     VariantClear(&v);
4019
4020     V_VT(&v) = VT_BSTR;
4021     V_BSTR(&v) = a2bstr("1");
4022     hres = IHTMLStyle_put_zIndex(style, v);
4023     ok(hres == S_OK, "put_zIndex failed: %08x\n", hres);
4024     VariantClear(&v);
4025
4026     V_VT(&v) = VT_EMPTY;
4027     hres = IHTMLStyle_get_zIndex(style, &v);
4028     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
4029     ok(V_VT(&v) == VT_I4, "V_VT(v)=%d\n", V_VT(&v));
4030     ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v));
4031     VariantClear(&v);
4032
4033     /* fontStyle */
4034     hres = IHTMLStyle_get_fontStyle(style, &sDefault);
4035     ok(hres == S_OK, "get_fontStyle failed: %08x\n", hres);
4036
4037     str = a2bstr("test");
4038     hres = IHTMLStyle_put_fontStyle(style, str);
4039     ok(hres == E_INVALIDARG, "put_fontStyle failed: %08x\n", hres);
4040     SysFreeString(str);
4041
4042     str = a2bstr("italic");
4043     hres = IHTMLStyle_put_fontStyle(style, str);
4044     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4045     SysFreeString(str);
4046
4047     str = a2bstr("oblique");
4048     hres = IHTMLStyle_put_fontStyle(style, str);
4049     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4050     SysFreeString(str);
4051
4052     str = a2bstr("normal");
4053     hres = IHTMLStyle_put_fontStyle(style, str);
4054     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4055     SysFreeString(str);
4056
4057     hres = IHTMLStyle_put_fontStyle(style, sDefault);
4058     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4059     SysFreeString(sDefault);
4060
4061     /* overflow */
4062     hres = IHTMLStyle_get_overflow(style, NULL);
4063     ok(hres == E_INVALIDARG, "get_overflow failed: %08x\n", hres);
4064
4065     hres = IHTMLStyle_get_overflow(style, &sOverflowDefault);
4066     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
4067
4068     str = a2bstr("test");
4069     hres = IHTMLStyle_put_overflow(style, str);
4070     ok(hres == E_INVALIDARG, "put_overflow failed: %08x\n", hres);
4071     SysFreeString(str);
4072
4073     str = a2bstr("visible");
4074     hres = IHTMLStyle_put_overflow(style, str);
4075     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4076     SysFreeString(str);
4077
4078     str = a2bstr("scroll");
4079     hres = IHTMLStyle_put_overflow(style, str);
4080     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4081     SysFreeString(str);
4082
4083     str = a2bstr("hidden");
4084     hres = IHTMLStyle_put_overflow(style, str);
4085     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4086     SysFreeString(str);
4087
4088     str = a2bstr("auto");
4089     hres = IHTMLStyle_put_overflow(style, str);
4090     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4091     SysFreeString(str);
4092
4093     hres = IHTMLStyle_get_overflow(style, &str);
4094     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
4095     ok(!strcmp_wa(str, "auto"), "str=%s\n", wine_dbgstr_w(str));
4096     SysFreeString(str);
4097
4098     str = a2bstr("");
4099     hres = IHTMLStyle_put_overflow(style, str);
4100     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4101     SysFreeString(str);
4102
4103     hres = IHTMLStyle_get_overflow(style, &str);
4104     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
4105     ok(!str, "str=%s\n", wine_dbgstr_w(str));
4106     SysFreeString(str);
4107
4108     /* restore overflow default */
4109     hres = IHTMLStyle_put_overflow(style, sOverflowDefault);
4110     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4111     SysFreeString(sOverflowDefault);
4112
4113     /* Attribute Tests*/
4114     hres = IHTMLStyle_getAttribute(style, NULL, 1, &v);
4115     ok(hres == E_INVALIDARG, "getAttribute failed: %08x\n", hres);
4116
4117     str = a2bstr("position");
4118     hres = IHTMLStyle_getAttribute(style, str, 1, NULL);
4119     ok(hres == E_INVALIDARG, "getAttribute failed: %08x\n", hres);
4120
4121     hres = IHTMLStyle_getAttribute(style, str, 1, &v);
4122     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
4123     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4124     VariantClear(&v);
4125
4126     hres = IHTMLStyle_setAttribute(style, NULL, v, 1);
4127     ok(hres == E_INVALIDARG, "setAttribute failed: %08x\n", hres);
4128
4129     V_VT(&v) = VT_BSTR;
4130     V_BSTR(&v) = a2bstr("absolute");
4131     hres = IHTMLStyle_setAttribute(style, str, v, 1);
4132     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
4133     VariantClear(&v);
4134
4135     hres = IHTMLStyle_getAttribute(style, str, 1, &v);
4136     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
4137     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4138     ok(!strcmp_wa(V_BSTR(&v), "absolute"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4139     VariantClear(&v);
4140
4141     V_VT(&v) = VT_BSTR;
4142     V_BSTR(&v) = NULL;
4143     hres = IHTMLStyle_setAttribute(style, str, v, 1);
4144     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
4145     VariantClear(&v);
4146
4147     SysFreeString(str);
4148
4149     str = a2bstr("borderLeftStyle");
4150     test_border_styles(style, str);
4151     SysFreeString(str);
4152
4153     str = a2bstr("borderbottomstyle");
4154     test_border_styles(style, str);
4155     SysFreeString(str);
4156
4157     str = a2bstr("borderrightstyle");
4158     test_border_styles(style, str);
4159     SysFreeString(str);
4160
4161     str = a2bstr("bordertopstyle");
4162     test_border_styles(style, str);
4163     SysFreeString(str);
4164
4165     hres = IHTMLStyle_get_borderStyle(style, &sDefault);
4166     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
4167
4168     str = a2bstr("none dotted dashed solid");
4169     hres = IHTMLStyle_put_borderStyle(style, str);
4170     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4171     SysFreeString(str);
4172
4173     str = a2bstr("none dotted dashed solid");
4174     hres = IHTMLStyle_get_borderStyle(style, &str);
4175     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
4176     ok(!strcmp_wa(str, "none dotted dashed solid"),
4177         "expected (none dotted dashed solid) = (%s)\n", wine_dbgstr_w(V_BSTR(&v)));
4178     SysFreeString(str);
4179
4180     str = a2bstr("double groove ridge inset");
4181     hres = IHTMLStyle_put_borderStyle(style, str);
4182     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4183     SysFreeString(str);
4184
4185     str = a2bstr("window-inset outset ridge inset");
4186     hres = IHTMLStyle_put_borderStyle(style, str);
4187     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4188     SysFreeString(str);
4189
4190     str = a2bstr("window-inset");
4191     hres = IHTMLStyle_put_borderStyle(style, str);
4192     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4193     SysFreeString(str);
4194
4195     str = a2bstr("none none none none none");
4196     hres = IHTMLStyle_put_borderStyle(style, str);
4197     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4198     SysFreeString(str);
4199
4200     str = a2bstr("invalid none none none");
4201     hres = IHTMLStyle_put_borderStyle(style, str);
4202     ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres);
4203     SysFreeString(str);
4204
4205     str = a2bstr("none invalid none none");
4206     hres = IHTMLStyle_put_borderStyle(style, str);
4207     ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres);
4208     SysFreeString(str);
4209
4210     hres = IHTMLStyle_put_borderStyle(style, sDefault);
4211     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4212     SysFreeString(sDefault);
4213
4214     /* backgoundColor */
4215     hres = IHTMLStyle_get_backgroundColor(style, &v);
4216     ok(hres == S_OK, "get_backgroundColor: %08x\n", hres);
4217     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4218     ok(!V_BSTR(&v), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4219     VariantClear(&v);
4220
4221     /* PaddingLeft */
4222     hres = IHTMLStyle_get_paddingLeft(style, &vDefault);
4223     ok(hres == S_OK, "get_paddingLeft: %08x\n", hres);
4224
4225     V_VT(&v) = VT_BSTR;
4226     V_BSTR(&v) = a2bstr("10");
4227     hres = IHTMLStyle_put_paddingLeft(style, v);
4228     ok(hres == S_OK, "put_paddingLeft: %08x\n", hres);
4229     VariantClear(&v);
4230
4231     hres = IHTMLStyle_get_paddingLeft(style, &v);
4232     ok(hres == S_OK, "get_paddingLeft: %08x\n", hres);
4233     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expecte 10 = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4234
4235     hres = IHTMLStyle_put_paddingLeft(style, vDefault);
4236     ok(hres == S_OK, "put_paddingLeft: %08x\n", hres);
4237
4238     /* BackgroundRepeat */
4239     hres = IHTMLStyle_get_backgroundRepeat(style, &sDefault);
4240     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
4241
4242     str = a2bstr("invalid");
4243     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4244     ok(hres == E_INVALIDARG, "put_backgroundRepeat failed: %08x\n", hres);
4245     SysFreeString(str);
4246
4247     str = a2bstr("repeat");
4248     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4249     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4250     SysFreeString(str);
4251
4252     str = a2bstr("no-repeat");
4253     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4254     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4255     SysFreeString(str);
4256
4257     str = a2bstr("repeat-x");
4258     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4259     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4260     SysFreeString(str);
4261
4262     str = a2bstr("repeat-y");
4263     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4264     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4265     SysFreeString(str);
4266
4267     hres = IHTMLStyle_get_backgroundRepeat(style, &str);
4268     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
4269     ok(!strcmp_wa(str, "repeat-y"), "str=%s\n", wine_dbgstr_w(str));
4270     SysFreeString(str);
4271
4272     hres = IHTMLStyle_put_backgroundRepeat(style, sDefault);
4273     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4274     SysFreeString(sDefault);
4275
4276     /* BorderColor */
4277     hres = IHTMLStyle_get_borderColor(style, &sDefault);
4278     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
4279
4280     str = a2bstr("red green red blue");
4281     hres = IHTMLStyle_put_borderColor(style, str);
4282     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
4283     SysFreeString(str);
4284
4285     hres = IHTMLStyle_get_borderColor(style, &str);
4286     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
4287     ok(!strcmp_wa(str, "red green red blue"), "str=%s\n", wine_dbgstr_w(str));
4288     SysFreeString(str);
4289
4290     hres = IHTMLStyle_put_borderColor(style, sDefault);
4291     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
4292     SysFreeString(sDefault);
4293
4294     /* BorderRight */
4295     hres = IHTMLStyle_get_borderRight(style, &sDefault);
4296     ok(hres == S_OK, "get_borderRight failed: %08x\n", hres);
4297
4298     str = a2bstr("thick dotted red");
4299     hres = IHTMLStyle_put_borderRight(style, str);
4300     ok(hres == S_OK, "put_borderRight failed: %08x\n", hres);
4301     SysFreeString(str);
4302
4303     /* IHTMLStyle_get_borderRight appears to have a bug where
4304         it returns the first letter of the color.  So we check
4305         each style individually.
4306      */
4307     V_BSTR(&v) = NULL;
4308     hres = IHTMLStyle_get_borderRightColor(style, &v);
4309     todo_wine ok(hres == S_OK, "get_borderRightColor failed: %08x\n", hres);
4310     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4311     VariantClear(&v);
4312
4313     V_BSTR(&v) = NULL;
4314     hres = IHTMLStyle_get_borderRightWidth(style, &v);
4315     ok(hres == S_OK, "get_borderRightWidth failed: %08x\n", hres);
4316     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4317     VariantClear(&v);
4318
4319     hres = IHTMLStyle_get_borderRightStyle(style, &str);
4320     ok(hres == S_OK, "get_borderRightStyle failed: %08x\n", hres);
4321     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4322     SysFreeString(str);
4323
4324     hres = IHTMLStyle_put_borderRight(style, sDefault);
4325     ok(hres == S_OK, "put_borderRight failed: %08x\n", hres);
4326     SysFreeString(sDefault);
4327
4328     /* BorderTop */
4329     hres = IHTMLStyle_get_borderTop(style, &sDefault);
4330     ok(hres == S_OK, "get_borderTop failed: %08x\n", hres);
4331
4332     str = a2bstr("thick dotted red");
4333     hres = IHTMLStyle_put_borderTop(style, str);
4334     ok(hres == S_OK, "put_borderTop failed: %08x\n", hres);
4335     SysFreeString(str);
4336
4337     /* IHTMLStyle_get_borderTop appears to have a bug where
4338         it returns the first letter of the color.  So we check
4339         each style individually.
4340      */
4341     V_BSTR(&v) = NULL;
4342     hres = IHTMLStyle_get_borderTopColor(style, &v);
4343     todo_wine ok(hres == S_OK, "get_borderTopColor failed: %08x\n", hres);
4344     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4345     VariantClear(&v);
4346
4347     V_BSTR(&v) = NULL;
4348     hres = IHTMLStyle_get_borderTopWidth(style, &v);
4349     ok(hres == S_OK, "get_borderTopWidth failed: %08x\n", hres);
4350     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4351     VariantClear(&v);
4352
4353     hres = IHTMLStyle_get_borderTopStyle(style, &str);
4354     ok(hres == S_OK, "get_borderTopStyle failed: %08x\n", hres);
4355     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4356     SysFreeString(str);
4357
4358     hres = IHTMLStyle_put_borderTop(style, sDefault);
4359     ok(hres == S_OK, "put_borderTop failed: %08x\n", hres);
4360     SysFreeString(sDefault);
4361
4362     /* BorderBottom */
4363     hres = IHTMLStyle_get_borderBottom(style, &sDefault);
4364     ok(hres == S_OK, "get_borderBottom failed: %08x\n", hres);
4365
4366     str = a2bstr("thick dotted red");
4367     hres = IHTMLStyle_put_borderBottom(style, str);
4368     ok(hres == S_OK, "put_borderBottom failed: %08x\n", hres);
4369     SysFreeString(str);
4370
4371     /* IHTMLStyle_get_borderBottom appears to have a bug where
4372         it returns the first letter of the color.  So we check
4373         each style individually.
4374      */
4375     V_BSTR(&v) = NULL;
4376     hres = IHTMLStyle_get_borderBottomColor(style, &v);
4377     todo_wine ok(hres == S_OK, "get_borderBottomColor failed: %08x\n", hres);
4378     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4379     VariantClear(&v);
4380
4381     V_BSTR(&v) = NULL;
4382     hres = IHTMLStyle_get_borderBottomWidth(style, &v);
4383     ok(hres == S_OK, "get_borderBottomWidth failed: %08x\n", hres);
4384     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4385     VariantClear(&v);
4386
4387     hres = IHTMLStyle_get_borderBottomStyle(style, &str);
4388     ok(hres == S_OK, "get_borderBottomStyle failed: %08x\n", hres);
4389     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4390     SysFreeString(str);
4391
4392     hres = IHTMLStyle_put_borderBottom(style, sDefault);
4393     ok(hres == S_OK, "put_borderBottom failed: %08x\n", hres);
4394     SysFreeString(sDefault);
4395
4396     /* BorderLeft */
4397     hres = IHTMLStyle_get_borderLeft(style, &sDefault);
4398     ok(hres == S_OK, "get_borderLeft failed: %08x\n", hres);
4399
4400     str = a2bstr("thick dotted red");
4401     hres = IHTMLStyle_put_borderLeft(style, str);
4402     ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres);
4403     SysFreeString(str);
4404
4405     /* IHTMLStyle_get_borderLeft appears to have a bug where
4406         it returns the first letter of the color.  So we check
4407         each style individually.
4408      */
4409     V_BSTR(&v) = NULL;
4410     hres = IHTMLStyle_get_borderLeftColor(style, &v);
4411     todo_wine ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres);
4412     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4413     VariantClear(&v);
4414
4415     V_BSTR(&v) = NULL;
4416     hres = IHTMLStyle_get_borderLeftWidth(style, &v);
4417     ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres);
4418     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4419     VariantClear(&v);
4420
4421     hres = IHTMLStyle_get_borderLeftStyle(style, &str);
4422     ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres);
4423     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4424     SysFreeString(str);
4425
4426     hres = IHTMLStyle_put_borderLeft(style, sDefault);
4427     ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres);
4428     SysFreeString(sDefault);
4429
4430     /* backgroundPositionX */
4431     hres = IHTMLStyle_get_backgroundPositionX(style, &vDefault);
4432     ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres);
4433
4434     V_VT(&v) = VT_BSTR;
4435     V_BSTR(&v) = a2bstr("10px");
4436     hres = IHTMLStyle_put_backgroundPositionX(style, v);
4437     ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres);
4438     VariantClear(&v);
4439
4440     hres = IHTMLStyle_get_backgroundPositionX(style, &v);
4441     ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres);
4442     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4443     VariantClear(&v);
4444
4445     hres = IHTMLStyle_put_backgroundPositionX(style, vDefault);
4446     ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres);
4447     VariantClear(&vDefault);
4448
4449     /* backgroundPositionY */
4450     hres = IHTMLStyle_get_backgroundPositionY(style, &vDefault);
4451     ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres);
4452
4453     V_VT(&v) = VT_BSTR;
4454     V_BSTR(&v) = a2bstr("10px");
4455     hres = IHTMLStyle_put_backgroundPositionY(style, v);
4456     ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres);
4457     VariantClear(&v);
4458
4459     hres = IHTMLStyle_get_backgroundPositionY(style, &v);
4460     ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres);
4461     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4462     VariantClear(&v);
4463
4464     hres = IHTMLStyle_put_backgroundPositionY(style, vDefault);
4465     ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres);
4466     VariantClear(&vDefault);
4467
4468      /* borderTopWidth */
4469     hres = IHTMLStyle_get_borderTopWidth(style, &vDefault);
4470     ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres);
4471
4472     V_VT(&v) = VT_BSTR;
4473     V_BSTR(&v) = a2bstr("10px");
4474     hres = IHTMLStyle_put_borderTopWidth(style, v);
4475     ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres);
4476     VariantClear(&v);
4477
4478     hres = IHTMLStyle_get_borderTopWidth(style, &v);
4479     ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres);
4480     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4481     VariantClear(&v);
4482
4483     hres = IHTMLStyle_put_borderTopWidth(style, vDefault);
4484     ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres);
4485     VariantClear(&vDefault);
4486
4487     /* borderRightWidth */
4488     hres = IHTMLStyle_get_borderRightWidth(style, &vDefault);
4489     ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres);
4490
4491     V_VT(&v) = VT_BSTR;
4492     V_BSTR(&v) = a2bstr("10");
4493     hres = IHTMLStyle_put_borderRightWidth(style, v);
4494     ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres);
4495     VariantClear(&v);
4496
4497     hres = IHTMLStyle_get_borderRightWidth(style, &v);
4498     ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres);
4499     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4500     VariantClear(&v);
4501
4502     hres = IHTMLStyle_put_borderRightWidth(style, vDefault);
4503     ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres);
4504     VariantClear(&vDefault);
4505
4506     /* borderBottomWidth */
4507     hres = IHTMLStyle_get_borderBottomWidth(style, &vDefault);
4508     ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres);
4509
4510     V_VT(&v) = VT_BSTR;
4511     V_BSTR(&v) = a2bstr("10");
4512     hres = IHTMLStyle_put_borderBottomWidth(style, v);
4513     ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres);
4514     VariantClear(&v);
4515
4516     hres = IHTMLStyle_get_borderBottomWidth(style, &v);
4517     ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres);
4518     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4519     VariantClear(&v);
4520
4521     hres = IHTMLStyle_put_borderBottomWidth(style, vDefault);
4522     ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres);
4523     VariantClear(&vDefault);
4524
4525     /* borderLeftWidth */
4526     hres = IHTMLStyle_get_borderLeftWidth(style, &vDefault);
4527     ok(hres == S_OK, "get_borderLeftWidth: %08x\n", hres);
4528
4529     V_VT(&v) = VT_BSTR;
4530     V_BSTR(&v) = a2bstr("10");
4531     hres = IHTMLStyle_put_borderLeftWidth(style, v);
4532     ok(hres == S_OK, "put_borderLeftWidth: %08x\n", hres);
4533     VariantClear(&v);
4534
4535     hres = IHTMLStyle_get_borderLeftWidth(style, &v);
4536     ok(hres == S_OK, "get_borderLeftWidth: %08x\n", hres);
4537     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4538     VariantClear(&v);
4539
4540     hres = IHTMLStyle_put_borderLeftWidth(style, vDefault);
4541     ok(hres == S_OK, "put_borderLeftWidth: %08x\n", hres);
4542     VariantClear(&vDefault);
4543
4544     /* wordSpacing */
4545     hres = IHTMLStyle_get_wordSpacing(style, &vDefault);
4546     ok(hres == S_OK, "get_wordSpacing: %08x\n", hres);
4547
4548     V_VT(&v) = VT_BSTR;
4549     V_BSTR(&v) = a2bstr("10");
4550     hres = IHTMLStyle_put_wordSpacing(style, v);
4551     ok(hres == S_OK, "put_wordSpacing: %08x\n", hres);
4552     VariantClear(&v);
4553
4554     hres = IHTMLStyle_get_wordSpacing(style, &v);
4555     ok(hres == S_OK, "get_wordSpacing: %08x\n", hres);
4556     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4557     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4558     VariantClear(&v);
4559
4560     hres = IHTMLStyle_put_wordSpacing(style, vDefault);
4561     ok(hres == S_OK, "put_wordSpacing: %08x\n", hres);
4562     VariantClear(&vDefault);
4563
4564     /* letterSpacing */
4565     hres = IHTMLStyle_get_letterSpacing(style, &vDefault);
4566     ok(hres == S_OK, "get_letterSpacing: %08x\n", hres);
4567
4568     V_VT(&v) = VT_BSTR;
4569     V_BSTR(&v) = a2bstr("11");
4570     hres = IHTMLStyle_put_letterSpacing(style, v);
4571     ok(hres == S_OK, "put_letterSpacing: %08x\n", hres);
4572     VariantClear(&v);
4573
4574     hres = IHTMLStyle_get_letterSpacing(style, &v);
4575     ok(hres == S_OK, "get_letterSpacing: %08x\n", hres);
4576     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4577     ok(!strcmp_wa(V_BSTR(&v), "11px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4578     VariantClear(&v);
4579
4580     hres = IHTMLStyle_put_letterSpacing(style, vDefault);
4581     ok(hres == S_OK, "put_letterSpacing: %08x\n", hres);
4582     VariantClear(&vDefault);
4583
4584     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle2, (void**)&style2);
4585     ok(hres == S_OK, "Could not get IHTMLStyle2 iface: %08x\n", hres);
4586     if(SUCCEEDED(hres)) {
4587         test_style2(style2);
4588         IHTMLStyle2_Release(style2);
4589     }
4590
4591     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle3, (void**)&style3);
4592     ok(hres == S_OK, "Could not get IHTMLStyle3 iface: %08x\n", hres);
4593     if(SUCCEEDED(hres)) {
4594         test_style3(style3);
4595         IHTMLStyle3_Release(style3);
4596     }
4597
4598     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle4, (void**)&style4);
4599     ok(hres == S_OK, "Could not get IHTMLStyle4 iface: %08x\n", hres);
4600     if(SUCCEEDED(hres)) {
4601         test_style4(style4);
4602         IHTMLStyle4_Release(style4);
4603     }
4604 }
4605
4606 static void test_set_csstext(IHTMLStyle *style)
4607 {
4608     VARIANT v;
4609     HRESULT hres;
4610
4611     test_style_set_csstext(style, "background-color: black;");
4612
4613     hres = IHTMLStyle_get_backgroundColor(style, &v);
4614     ok(hres == S_OK, "get_backgroundColor: %08x\n", hres);
4615     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4616     ok(!strcmp_wa(V_BSTR(&v), "black"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4617     VariantClear(&v);
4618 }
4619
4620 static void test_default_selection(IHTMLDocument2 *doc)
4621 {
4622     IHTMLSelectionObject *selection;
4623     IHTMLTxtRange *range;
4624     IDispatch *disp;
4625     BSTR str;
4626     HRESULT hres;
4627
4628     hres = IHTMLDocument2_get_selection(doc, &selection);
4629     ok(hres == S_OK, "get_selection failed: %08x\n", hres);
4630
4631     hres = IHTMLSelectionObject_get_type(selection, &str);
4632     ok(hres == S_OK, "get_type failed: %08x\n", hres);
4633     ok(!strcmp_wa(str, "None"), "type = %s\n", wine_dbgstr_w(str));
4634     SysFreeString(str);
4635
4636     hres = IHTMLSelectionObject_createRange(selection, &disp);
4637     IHTMLSelectionObject_Release(selection);
4638     ok(hres == S_OK, "createRange failed: %08x\n", hres);
4639
4640     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTxtRange, (void**)&range);
4641     IDispatch_Release(disp);
4642     ok(hres == S_OK, "Could not get IHTMLTxtRange interface: %08x\n", hres);
4643
4644     test_range_text(range, NULL);
4645     IHTMLTxtRange_Release(range);
4646 }
4647
4648 static void test_doc_elem(IHTMLDocument2 *doc)
4649 {
4650     IHTMLDocument2 *doc_node, *owner_doc;
4651     IHTMLElement *elem;
4652     IHTMLDocument3 *doc3;
4653     HRESULT hres;
4654
4655     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4656     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
4657
4658     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
4659     IHTMLDocument3_Release(doc3);
4660     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
4661
4662     test_node_name((IUnknown*)elem, "HTML");
4663     test_elem_tag((IUnknown*)elem, "HTML");
4664
4665     doc_node = get_doc_node(doc);
4666     owner_doc = get_owner_doc((IUnknown*)elem);
4667     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
4668     IHTMLDocument2_Release(owner_doc);
4669
4670     owner_doc = get_owner_doc((IUnknown*)doc_node);
4671     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
4672     IHTMLDocument2_Release(doc_node);
4673
4674     test_elem_client_rect((IUnknown*)elem);
4675
4676     IHTMLElement_Release(elem);
4677 }
4678
4679 static void test_default_body(IHTMLBodyElement *body)
4680 {
4681     LONG l;
4682     BSTR bstr;
4683     HRESULT hres;
4684     VARIANT v;
4685     WCHAR sBodyText[] = {'#','F','F','0','0','0','0',0};
4686     WCHAR sTextInvalid[] = {'I','n','v','a','l','i','d',0};
4687
4688     bstr = (void*)0xdeadbeef;
4689     hres = IHTMLBodyElement_get_background(body, &bstr);
4690     ok(hres == S_OK, "get_background failed: %08x\n", hres);
4691     ok(bstr == NULL, "bstr != NULL\n");
4692
4693     l = elem_get_scroll_height((IUnknown*)body);
4694     ok(l != -1, "scrollHeight == -1\n");
4695     l = elem_get_scroll_width((IUnknown*)body);
4696     ok(l != -1, "scrollWidth == -1\n");
4697     l = elem_get_scroll_top((IUnknown*)body);
4698     ok(!l, "scrollTop = %d\n", l);
4699     elem_get_scroll_left((IUnknown*)body);
4700
4701     /* get_text tests */
4702     hres = IHTMLBodyElement_get_text(body, &v);
4703     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4704     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4705     ok(bstr == NULL, "bstr != NULL\n");
4706
4707
4708     /* get_text - Invalid Text */
4709     V_VT(&v) = VT_BSTR;
4710     V_BSTR(&v) = SysAllocString(sTextInvalid);
4711     hres = IHTMLBodyElement_put_text(body, v);
4712     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4713     VariantClear(&v);
4714
4715     V_VT(&v) = VT_NULL;
4716     hres = IHTMLBodyElement_get_text(body, &v);
4717     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4718     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4719     ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v != '#00a0d0'\n");
4720     VariantClear(&v);
4721
4722     /* get_text - Valid Text */
4723     V_VT(&v) = VT_BSTR;
4724     V_BSTR(&v) = SysAllocString(sBodyText);
4725     hres = IHTMLBodyElement_put_text(body, v);
4726     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4727     VariantClear(&v);
4728
4729     V_VT(&v) = VT_NULL;
4730     hres = IHTMLBodyElement_get_text(body, &v);
4731     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4732     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4733     ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v != '#ff0000'\n");
4734     VariantClear(&v);
4735 }
4736
4737 static void test_body_funs(IHTMLBodyElement *body)
4738 {
4739     static WCHAR sRed[] = {'r','e','d',0};
4740     VARIANT vbg;
4741     VARIANT vDefaultbg;
4742     HRESULT hres;
4743
4744     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
4745     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4746     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
4747
4748     V_VT(&vbg) = VT_BSTR;
4749     V_BSTR(&vbg) = SysAllocString(sRed);
4750     hres = IHTMLBodyElement_put_bgColor(body, vbg);
4751     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4752     VariantClear(&vbg);
4753
4754     hres = IHTMLBodyElement_get_bgColor(body, &vbg);
4755     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4756     ok(V_VT(&vDefaultbg) == VT_BSTR, "V_VT(&vDefaultbg) != VT_BSTR\n");
4757     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
4758     VariantClear(&vbg);
4759
4760     /* Restore Originial */
4761     hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg);
4762     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4763     VariantClear(&vDefaultbg);
4764 }
4765
4766 static void test_window(IHTMLDocument2 *doc)
4767 {
4768     IHTMLWindow2 *window, *window2, *self;
4769     IHTMLDocument2 *doc2 = NULL;
4770     IDispatch *disp;
4771     IUnknown *unk;
4772     BSTR str;
4773     HRESULT hres;
4774
4775     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4776     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
4777     test_ifaces((IUnknown*)window, window_iids);
4778     test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, "[object]");
4779
4780     hres = IHTMLWindow2_get_document(window, &doc2);
4781     ok(hres == S_OK, "get_document failed: %08x\n", hres);
4782     ok(doc2 != NULL, "doc2 == NULL\n");
4783
4784     test_ifaces((IUnknown*)doc2, doc_node_iids);
4785     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
4786
4787     test_ifaces((IUnknown*)doc, doc_obj_iids);
4788     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
4789
4790     unk = (void*)0xdeadbeef;
4791     hres = IHTMLDocument2_QueryInterface(doc2, &IID_ICustomDoc, (void**)&unk);
4792     ok(hres == E_NOINTERFACE, "QueryInterface(IID_ICustomDoc) returned: %08x\n", hres);
4793     ok(!unk, "unk = %p\n", unk);
4794
4795     IHTMLDocument_Release(doc2);
4796
4797     hres = IHTMLWindow2_get_window(window, &window2);
4798     ok(hres == S_OK, "get_window failed: %08x\n", hres);
4799     ok(window2 != NULL, "window2 == NULL\n");
4800
4801     hres = IHTMLWindow2_get_self(window, &self);
4802     ok(hres == S_OK, "get_self failed: %08x\n", hres);
4803     ok(window2 != NULL, "self == NULL\n");
4804
4805     ok(self == window2, "self != window2\n");
4806
4807     IHTMLWindow2_Release(window2);
4808     IHTMLWindow2_Release(self);
4809
4810     disp = NULL;
4811     hres = IHTMLDocument2_get_Script(doc, &disp);
4812     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
4813     ok(disp == (void*)window, "disp != window\n");
4814     IDispatch_Release(disp);
4815
4816     hres = IHTMLWindow2_toString(window, NULL);
4817     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
4818
4819     str = NULL;
4820     hres = IHTMLWindow2_toString(window, &str);
4821     ok(hres == S_OK, "toString failed: %08x\n", hres);
4822     ok(!strcmp_wa(str, "[object]"), "toString returned %s\n", wine_dbgstr_w(str));
4823     SysFreeString(str);
4824
4825     test_window_name(window, NULL);
4826     set_window_name(window, "test");
4827     test_window_length(window, 0);
4828     test_screen(window);
4829
4830     IHTMLWindow2_Release(window);
4831 }
4832
4833 static void test_defaults(IHTMLDocument2 *doc)
4834 {
4835     IHTMLStyleSheetsCollection *stylesheetcol;
4836     IHTMLCurrentStyle *cstyle;
4837     IHTMLBodyElement *body;
4838     IHTMLElement2 *elem2;
4839     IHTMLElement *elem;
4840     IHTMLStyle *style;
4841     LONG l;
4842     HRESULT hres;
4843     IHTMLElementCollection *collection;
4844
4845     hres = IHTMLDocument2_get_body(doc, &elem);
4846     ok(hres == S_OK, "get_body failed: %08x\n", hres);
4847
4848     hres = IHTMLDocument2_get_images(doc, NULL);
4849     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4850
4851     hres = IHTMLDocument2_get_images(doc, &collection);
4852     ok(hres == S_OK, "get_images failed: %08x\n", hres);
4853     if(hres == S_OK)
4854     {
4855         test_elem_collection((IUnknown*)collection, NULL, 0);
4856         IHTMLElementCollection_Release(collection);
4857     }
4858
4859     hres = IHTMLDocument2_get_applets(doc, NULL);
4860     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4861
4862     hres = IHTMLDocument2_get_applets(doc, &collection);
4863     ok(hres == S_OK, "get_applets failed: %08x\n", hres);
4864     if(hres == S_OK)
4865     {
4866         test_elem_collection((IUnknown*)collection, NULL, 0);
4867         IHTMLElementCollection_Release(collection);
4868     }
4869
4870     hres = IHTMLDocument2_get_links(doc, NULL);
4871     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4872
4873     hres = IHTMLDocument2_get_links(doc, &collection);
4874     ok(hres == S_OK, "get_links failed: %08x\n", hres);
4875     if(hres == S_OK)
4876     {
4877         test_elem_collection((IUnknown*)collection, NULL, 0);
4878         IHTMLElementCollection_Release(collection);
4879     }
4880
4881     hres = IHTMLDocument2_get_forms(doc, NULL);
4882     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4883
4884     hres = IHTMLDocument2_get_forms(doc, &collection);
4885     ok(hres == S_OK, "get_forms failed: %08x\n", hres);
4886     if(hres == S_OK)
4887     {
4888         test_elem_collection((IUnknown*)collection, NULL, 0);
4889         IHTMLElementCollection_Release(collection);
4890     }
4891
4892     hres = IHTMLDocument2_get_anchors(doc, NULL);
4893     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4894
4895     hres = IHTMLDocument2_get_anchors(doc, &collection);
4896     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
4897     if(hres == S_OK)
4898     {
4899         test_elem_collection((IUnknown*)collection, NULL, 0);
4900         IHTMLElementCollection_Release(collection);
4901     }
4902
4903     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
4904     ok(hres == S_OK, "Could not get IHTMBodyElement: %08x\n", hres);
4905     test_default_body(body);
4906     test_body_funs(body);
4907     IHTMLBodyElement_Release(body);
4908
4909     hres = IHTMLElement_get_style(elem, &style);
4910     ok(hres == S_OK, "get_style failed: %08x\n", hres);
4911
4912     test_default_style(style);
4913     test_window(doc);
4914     test_compatmode(doc);
4915     test_location(doc);
4916     test_navigator(doc);
4917
4918     elem2 = get_elem2_iface((IUnknown*)elem);
4919     hres = IHTMLElement2_get_currentStyle(elem2, &cstyle);
4920     ok(hres == S_OK, "get_currentStyle failed: %08x\n", hres);
4921     if(SUCCEEDED(hres)) {
4922         test_current_style(cstyle);
4923         IHTMLCurrentStyle_Release(cstyle);
4924     }
4925     IHTMLElement2_Release(elem2);
4926
4927     IHTMLElement_Release(elem);
4928
4929     test_set_csstext(style);
4930     IHTMLStyle_Release(style);
4931
4932     hres = IHTMLDocument2_get_styleSheets(doc, &stylesheetcol);
4933     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
4934
4935     l = 0xdeadbeef;
4936     hres = IHTMLStyleSheetsCollection_get_length(stylesheetcol, &l);
4937     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4938     ok(l == 0, "length = %d\n", l);
4939
4940     IHTMLStyleSheetsCollection_Release(stylesheetcol);
4941
4942     test_default_selection(doc);
4943     test_doc_title(doc, "");
4944 }
4945
4946 static void test_tr_elem(IHTMLElement *elem)
4947 {
4948     IHTMLElementCollection *col;
4949     IHTMLTableRow *row;
4950     HRESULT hres;
4951
4952     static const elem_type_t cell_types[] = {ET_TD,ET_TD};
4953
4954     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableRow, (void**)&row);
4955     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
4956     if(FAILED(hres))
4957         return;
4958
4959     col = NULL;
4960     hres = IHTMLTableRow_get_cells(row, &col);
4961     ok(hres == S_OK, "get_cells failed: %08x\n", hres);
4962     ok(col != NULL, "get_cells returned NULL\n");
4963
4964     test_elem_collection((IUnknown*)col, cell_types, sizeof(cell_types)/sizeof(*cell_types));
4965     IHTMLElementCollection_Release(col);
4966
4967     IHTMLTable_Release(row);
4968 }
4969
4970 static void test_table_elem(IHTMLElement *elem)
4971 {
4972     IHTMLElementCollection *col;
4973     IHTMLTable *table;
4974     IHTMLDOMNode *node;
4975     HRESULT hres;
4976
4977     static const elem_type_t row_types[] = {ET_TR,ET_TR};
4978     static const elem_type_t all_types[] = {ET_TBODY,ET_TR,ET_TR,ET_TD,ET_TD};
4979
4980     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable, (void**)&table);
4981     ok(hres == S_OK, "Could not get IHTMLTable iface: %08x\n", hres);
4982     if(FAILED(hres))
4983         return;
4984
4985     col = NULL;
4986     hres = IHTMLTable_get_rows(table, &col);
4987     ok(hres == S_OK, "get_rows failed: %08x\n", hres);
4988     ok(col != NULL, "get_ros returned NULL\n");
4989
4990     test_elem_collection((IUnknown*)col, row_types, sizeof(row_types)/sizeof(*row_types));
4991     IHTMLElementCollection_Release(col);
4992
4993     test_elem_all((IUnknown*)table, all_types, sizeof(all_types)/sizeof(*all_types));
4994
4995     node = clone_node((IUnknown*)table, VARIANT_TRUE);
4996     test_elem_tag((IUnknown*)node, "TABLE");
4997     test_elem_all((IUnknown*)node, all_types, sizeof(all_types)/sizeof(*all_types));
4998     IHTMLDOMNode_Release(node);
4999
5000     node = clone_node((IUnknown*)table, VARIANT_FALSE);
5001     test_elem_tag((IUnknown*)node, "TABLE");
5002     test_elem_all((IUnknown*)node, NULL, 0);
5003     IHTMLDOMNode_Release(node);
5004
5005     IHTMLTable_Release(table);
5006 }
5007
5008 static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
5009 {
5010     SAFEARRAYBOUND dim;
5011     SAFEARRAY *sa;
5012     VARIANT *var;
5013     BSTR str;
5014     HRESULT hres;
5015
5016     dim.lLbound = 0;
5017     dim.cElements = 1;
5018     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
5019     SafeArrayAccessData(sa, (void**)&var);
5020     V_VT(var) = VT_BSTR;
5021     V_BSTR(var) = str = a2bstr(text);
5022     SafeArrayUnaccessData(sa);
5023
5024     if(ln)
5025         hres = IHTMLDocument2_writeln(doc, sa);
5026     else
5027         hres = IHTMLDocument2_write(doc, sa);
5028     ok(hres == S_OK, "write failed: %08x\n", hres);
5029
5030     SysFreeString(str);
5031     SafeArrayDestroy(sa);
5032 }
5033
5034 static void test_frame_doc(IUnknown *frame_elem)
5035 {
5036     IHTMLDocument2 *window_doc, *elem_doc;
5037     IHTMLWindow2 *content_window;
5038
5039     content_window = get_frame_content_window(frame_elem);
5040     window_doc = get_window_doc(content_window);
5041     IHTMLWindow2_Release(content_window);
5042
5043     elem_doc = get_elem_doc(frame_elem);
5044     ok(iface_cmp((IUnknown*)window_doc, (IUnknown*)elem_doc), "content_doc != elem_doc\n");
5045
5046     IHTMLDocument2_Release(elem_doc);
5047     IHTMLDocument2_Release(window_doc);
5048 }
5049
5050 static void test_iframe_elem(IHTMLElement *elem)
5051 {
5052     IHTMLDocument2 *content_doc, *owner_doc;
5053     IHTMLElementCollection *col;
5054     IHTMLWindow2 *content_window;
5055     IDispatch *disp;
5056     VARIANT errv;
5057     BSTR str;
5058     HRESULT hres;
5059
5060     static const elem_type_t all_types[] = {
5061         ET_HTML,
5062         ET_HEAD,
5063         ET_TITLE,
5064         ET_BODY,
5065         ET_BR
5066     };
5067
5068     test_frame_doc((IUnknown*)elem);
5069
5070     content_window = get_frame_content_window((IUnknown*)elem);
5071     test_window_length(content_window, 0);
5072
5073     content_doc = get_window_doc(content_window);
5074     IHTMLWindow2_Release(content_window);
5075
5076     str = a2bstr("text/html");
5077     V_VT(&errv) = VT_ERROR;
5078     disp = NULL;
5079     hres = IHTMLDocument2_open(content_doc, str, errv, errv, errv, &disp);
5080     SysFreeString(str);
5081     ok(hres == S_OK, "open failed: %08x\n", hres);
5082     ok(disp != NULL, "disp == NULL\n");
5083     ok(iface_cmp((IUnknown*)disp, (IUnknown*)content_window), "disp != content_window\n");
5084     IDispatch_Release(disp);
5085
5086     doc_write(content_doc, FALSE, "<html><head><title>test</title></head><body><br /></body>");
5087     doc_write(content_doc, TRUE, "</html>");
5088
5089     hres = IHTMLDocument2_get_all(content_doc, &col);
5090     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5091     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5092     IHTMLElementCollection_Release(col);
5093
5094     hres = IHTMLDocument2_close(content_doc);
5095     ok(hres == S_OK, "close failed: %08x\n", hres);
5096
5097     owner_doc = get_owner_doc((IUnknown*)content_doc);
5098     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
5099
5100     IHTMLDocument2_Release(content_doc);
5101 }
5102
5103 static void test_stylesheet(IDispatch *disp)
5104 {
5105     IHTMLStyleSheetRulesCollection *col = NULL;
5106     IHTMLStyleSheet *stylesheet;
5107     HRESULT hres;
5108
5109     hres = IDispatch_QueryInterface(disp, &IID_IHTMLStyleSheet, (void**)&stylesheet);
5110     ok(hres == S_OK, "Could not get IHTMLStyleSheet: %08x\n", hres);
5111
5112     hres = IHTMLStyleSheet_get_rules(stylesheet, &col);
5113     ok(hres == S_OK, "get_rules failed: %08x\n", hres);
5114     ok(col != NULL, "col == NULL\n");
5115
5116     IHTMLStyleSheetRulesCollection_Release(col);
5117     IHTMLStyleSheet_Release(stylesheet);
5118 }
5119
5120 static void test_stylesheets(IHTMLDocument2 *doc)
5121 {
5122     IHTMLStyleSheetsCollection *col = NULL;
5123     VARIANT idx, res;
5124     LONG len = 0;
5125     HRESULT hres;
5126
5127     hres = IHTMLDocument2_get_styleSheets(doc, &col);
5128     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5129     ok(col != NULL, "col == NULL\n");
5130
5131     hres = IHTMLStyleSheetsCollection_get_length(col, &len);
5132     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5133     ok(len == 1, "len=%d\n", len);
5134
5135     VariantInit(&res);
5136     V_VT(&idx) = VT_I4;
5137     V_I4(&idx) = 0;
5138
5139     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5140     ok(hres == S_OK, "item failed: %08x\n", hres);
5141     ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
5142     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5143     test_stylesheet(V_DISPATCH(&res));
5144     VariantClear(&res);
5145
5146     V_VT(&res) = VT_I4;
5147     V_VT(&idx) = VT_I4;
5148     V_I4(&idx) = 1;
5149
5150     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5151     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5152     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
5153     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5154     VariantClear(&res);
5155
5156     IHTMLStyleSheetsCollection_Release(col);
5157 }
5158
5159 static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
5160 {
5161     IDispatchEx *dispex;
5162     IHTMLDOMNode *node;
5163     DISPPARAMS dp = {NULL, NULL, 0, 0};
5164     VARIANT var;
5165     EXCEPINFO ei;
5166     LONG type;
5167     DISPID id;
5168     BSTR bstr;
5169     HRESULT hres;
5170
5171     static const WCHAR w0[] = {'0',0};
5172     static const WCHAR w100[] = {'1','0','0',0};
5173
5174     hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
5175     ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
5176
5177     bstr = SysAllocString(w0);
5178     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5179     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5180     SysFreeString(bstr);
5181
5182     VariantInit(&var);
5183     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
5184     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
5185     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
5186     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
5187     node = get_node_iface((IUnknown*)V_DISPATCH(&var));
5188     type = get_node_type((IUnknown*)node);
5189     ok(type == 3, "type=%d\n", type);
5190     IHTMLDOMNode_Release(node);
5191     VariantClear(&var);
5192
5193     bstr = SysAllocString(w100);
5194     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5195     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
5196     SysFreeString(bstr);
5197
5198     IDispatchEx_Release(dispex);
5199 }
5200
5201
5202
5203 static void test_elems(IHTMLDocument2 *doc)
5204 {
5205     IHTMLElementCollection *col;
5206     IHTMLDOMChildrenCollection *child_col;
5207     IHTMLElement *elem, *elem2, *elem3;
5208     IHTMLDOMNode *node, *node2;
5209     IHTMLWindow2 *window;
5210     IDispatch *disp;
5211     LONG type;
5212     HRESULT hres;
5213     IHTMLElementCollection *collection;
5214     IHTMLDocument3 *doc3;
5215     BSTR str;
5216
5217     static const elem_type_t all_types[] = {
5218         ET_HTML,
5219         ET_HEAD,
5220         ET_TITLE,
5221         ET_STYLE,
5222         ET_BODY,
5223         ET_COMMENT,
5224         ET_A,
5225         ET_INPUT,
5226         ET_SELECT,
5227         ET_OPTION,
5228         ET_OPTION,
5229         ET_TEXTAREA,
5230         ET_TABLE,
5231         ET_TBODY,
5232         ET_TR,
5233         ET_TR,
5234         ET_TD,
5235         ET_TD,
5236         ET_SCRIPT,
5237         ET_TEST,
5238         ET_IMG,
5239         ET_IFRAME,
5240         ET_FORM
5241     };
5242
5243     static const elem_type_t item_types[] = {
5244         ET_A,
5245         ET_OPTION,
5246         ET_TEXTAREA
5247     };
5248
5249     hres = IHTMLDocument2_get_all(doc, &col);
5250     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5251     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5252     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
5253     IHTMLElementCollection_Release(col);
5254
5255     hres = IHTMLDocument2_get_images(doc, &collection);
5256     ok(hres == S_OK, "get_images failed: %08x\n", hres);
5257     if(hres == S_OK)
5258     {
5259         static const elem_type_t images_types[] = {ET_IMG};
5260         test_elem_collection((IUnknown*)collection, images_types, 1);
5261
5262         IHTMLElementCollection_Release(collection);
5263     }
5264
5265     hres = IHTMLDocument2_get_links(doc, &collection);
5266     ok(hres == S_OK, "get_links failed: %08x\n", hres);
5267     if(hres == S_OK)
5268     {
5269         static const elem_type_t images_types[] = {ET_A};
5270         test_elem_collection((IUnknown*)collection, images_types, 1);
5271
5272         IHTMLElementCollection_Release(collection);
5273     }
5274
5275     hres = IHTMLDocument2_get_anchors(doc, &collection);
5276     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5277     if(hres == S_OK)
5278     {
5279         static const elem_type_t anchor_types[] = {ET_A};
5280         test_elem_collection((IUnknown*)collection, anchor_types, 1);
5281
5282         IHTMLElementCollection_Release(collection);
5283     }
5284
5285     elem = get_doc_elem(doc);
5286     test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1);
5287     IHTMLElement_Release(elem);
5288
5289     get_elem_by_id(doc, "xxx", FALSE);
5290     elem = get_doc_elem_by_id(doc, "xxx");
5291     ok(!elem, "elem != NULL\n");
5292
5293     elem = get_doc_elem_by_id(doc, "s");
5294     ok(elem != NULL, "elem == NULL\n");
5295     if(elem) {
5296         test_elem_type((IUnknown*)elem, ET_SELECT);
5297         test_elem_attr(elem, "xxx", NULL);
5298         test_elem_attr(elem, "id", "s");
5299         test_elem_class((IUnknown*)elem, NULL);
5300         test_elem_set_class((IUnknown*)elem, "cl");
5301         test_elem_set_class((IUnknown*)elem, NULL);
5302         test_elem_tabindex((IUnknown*)elem, 0);
5303         test_elem_set_tabindex((IUnknown*)elem, 1);
5304
5305         node = test_node_get_parent((IUnknown*)elem);
5306         ok(node != NULL, "node == NULL\n");
5307         test_node_name((IUnknown*)node, "BODY");
5308         node2 = test_node_get_parent((IUnknown*)node);
5309         IHTMLDOMNode_Release(node);
5310         ok(node2 != NULL, "node == NULL\n");
5311         test_node_name((IUnknown*)node2, "HTML");
5312         node = test_node_get_parent((IUnknown*)node2);
5313         IHTMLDOMNode_Release(node2);
5314         ok(node != NULL, "node == NULL\n");
5315         if (node)
5316         {
5317             test_node_name((IUnknown*)node, "#document");
5318             type = get_node_type((IUnknown*)node);
5319             ok(type == 9, "type=%d, expected 9\n", type);
5320             node2 = test_node_get_parent((IUnknown*)node);
5321             IHTMLDOMNode_Release(node);
5322             ok(node2 == NULL, "node != NULL\n");
5323         }
5324
5325         elem2 = test_elem_get_parent((IUnknown*)elem);
5326         ok(elem2 != NULL, "elem2 == NULL\n");
5327         test_node_name((IUnknown*)elem2, "BODY");
5328         elem3 = test_elem_get_parent((IUnknown*)elem2);
5329         IHTMLElement_Release(elem2);
5330         ok(elem3 != NULL, "elem3 == NULL\n");
5331         test_node_name((IUnknown*)elem3, "HTML");
5332         elem2 = test_elem_get_parent((IUnknown*)elem3);
5333         IHTMLElement_Release(elem3);
5334         ok(elem2 == NULL, "elem2 != NULL\n");
5335
5336         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2);
5337         test_elem_getelembytag((IUnknown*)elem, ET_SELECT, 0);
5338         test_elem_getelembytag((IUnknown*)elem, ET_HTML, 0);
5339
5340         test_elem_innertext(elem, "opt1opt2");
5341
5342         IHTMLElement_Release(elem);
5343     }
5344
5345     elem = get_elem_by_id(doc, "s", TRUE);
5346     if(elem) {
5347         IHTMLSelectElement *select;
5348         IHTMLDocument2 *doc_node, *elem_doc;
5349
5350         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select);
5351         ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres);
5352
5353         test_select_elem(select);
5354
5355         test_elem_title((IUnknown*)select, NULL);
5356         test_elem_set_title((IUnknown*)select, "Title");
5357         test_elem_title((IUnknown*)select, "Title");
5358         test_elem_offset((IUnknown*)select);
5359
5360         node = get_first_child((IUnknown*)select);
5361         ok(node != NULL, "node == NULL\n");
5362         if(node) {
5363             test_elem_type((IUnknown*)node, ET_OPTION);
5364             IHTMLDOMNode_Release(node);
5365         }
5366
5367         type = get_node_type((IUnknown*)select);
5368         ok(type == 1, "type=%d\n", type);
5369
5370         IHTMLSelectElement_Release(select);
5371
5372         elem_doc = get_elem_doc((IUnknown*)elem);
5373
5374         doc_node = get_doc_node(doc);
5375         ok(iface_cmp((IUnknown*)elem_doc, (IUnknown*)doc_node), "disp != doc\n");
5376         IHTMLDocument2_Release(doc_node);
5377         IHTMLDocument2_Release(elem_doc);
5378
5379         IHTMLElement_Release(elem);
5380     }
5381
5382     elem = get_elem_by_id(doc, "sc", TRUE);
5383     if(elem) {
5384         IHTMLScriptElement *script;
5385         BSTR type;
5386
5387         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLScriptElement, (void**)&script);
5388         ok(hres == S_OK, "Could not get IHTMLScriptElement interface: %08x\n", hres);
5389
5390         if(hres == S_OK)
5391         {
5392             VARIANT_BOOL vb;
5393
5394             hres = IHTMLScriptElement_get_type(script, &type);
5395             ok(hres == S_OK, "get_type failed: %08x\n", hres);
5396             ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type));
5397             SysFreeString(type);
5398
5399             /* test defer */
5400             hres = IHTMLScriptElement_put_defer(script, VARIANT_TRUE);
5401             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5402
5403             hres = IHTMLScriptElement_get_defer(script, &vb);
5404             ok(hres == S_OK, "get_defer failed: %08x\n", hres);
5405             ok(vb == VARIANT_TRUE, "get_defer result is %08x\n", hres);
5406
5407             hres = IHTMLScriptElement_put_defer(script, VARIANT_FALSE);
5408             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5409         }
5410
5411         IHTMLScriptElement_Release(script);
5412     }
5413
5414     elem = get_elem_by_id(doc, "in", TRUE);
5415     if(elem) {
5416         IHTMLInputElement *input;
5417
5418         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLInputElement, (void**)&input);
5419         ok(hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
5420
5421         test_elem_id((IUnknown*)elem, "in");
5422         test_elem_put_id((IUnknown*)elem, "newin");
5423         test_input_get_disabled(input, VARIANT_FALSE);
5424         test_input_set_disabled(input, VARIANT_TRUE);
5425         test_input_set_disabled(input, VARIANT_FALSE);
5426         test_elem3_set_disabled((IUnknown*)input, VARIANT_TRUE);
5427         test_input_get_disabled(input, VARIANT_TRUE);
5428         test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE);
5429         test_input_get_disabled(input, VARIANT_FALSE);
5430         test_elem_client_size((IUnknown*)elem);
5431
5432         test_node_get_value_str((IUnknown*)elem, NULL);
5433         test_node_put_value_str((IUnknown*)elem, "test");
5434         test_node_get_value_str((IUnknown*)elem, NULL);
5435         test_input_value((IUnknown*)elem, NULL);
5436         test_input_put_value((IUnknown*)elem, "test");
5437         test_input_value((IUnknown*)elem, NULL);
5438         test_elem_class((IUnknown*)elem, "testclass");
5439         test_elem_tabindex((IUnknown*)elem, 2);
5440         test_elem_set_tabindex((IUnknown*)elem, 3);
5441         test_elem_title((IUnknown*)elem, "test title");
5442
5443         test_input_get_defaultchecked(input, VARIANT_FALSE);
5444         test_input_set_defaultchecked(input, VARIANT_TRUE);
5445         test_input_set_defaultchecked(input, VARIANT_FALSE);
5446
5447         test_input_get_checked(input, VARIANT_FALSE);
5448         test_input_set_checked(input, VARIANT_TRUE);
5449         test_input_set_checked(input, VARIANT_FALSE);
5450
5451         test_input_src(input, NULL);
5452         test_input_set_src(input, "about:blank");
5453
5454         IHTMLInputElement_Release(input);
5455         IHTMLElement_Release(elem);
5456     }
5457
5458     elem = get_elem_by_id(doc, "imgid", TRUE);
5459     if(elem) {
5460         test_img_src((IUnknown*)elem, "");
5461         test_img_set_src((IUnknown*)elem, "about:blank");
5462         test_img_alt((IUnknown*)elem, NULL);
5463         test_img_set_alt((IUnknown*)elem, "alt test");
5464         IHTMLElement_Release(elem);
5465     }
5466
5467     elem = get_doc_elem_by_id(doc, "tbl");
5468     ok(elem != NULL, "elem == NULL\n");
5469     if(elem) {
5470         test_table_elem(elem);
5471         IHTMLElement_Release(elem);
5472     }
5473
5474     elem = get_doc_elem_by_id(doc, "row2");
5475     ok(elem != NULL, "elem == NULL\n");
5476     if(elem) {
5477         test_tr_elem(elem);
5478         IHTMLElement_Release(elem);
5479     }
5480
5481     elem = get_doc_elem_by_id(doc, "ifr");
5482     ok(elem != NULL, "elem == NULL\n");
5483     if(elem) {
5484         test_iframe_elem(elem);
5485         IHTMLElement_Release(elem);
5486     }
5487
5488     elem = get_elem_by_id(doc, "a", TRUE);
5489     if(elem) {
5490         test_anchor_href((IUnknown*)elem, "http://test/");
5491         IHTMLElement_Release(elem);
5492     }
5493
5494     hres = IHTMLDocument2_get_body(doc, &elem);
5495     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5496
5497     node = get_first_child((IUnknown*)elem);
5498     ok(node != NULL, "node == NULL\n");
5499     if(node) {
5500         test_ifaces((IUnknown*)node, text_iids);
5501         test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
5502
5503         node2 = get_first_child((IUnknown*)node);
5504         ok(!node2, "node2 != NULL\n");
5505
5506         type = get_node_type((IUnknown*)node);
5507         ok(type == 3, "type=%d\n", type);
5508
5509         test_node_get_value_str((IUnknown*)node, "text test");
5510         test_node_put_value_str((IUnknown*)elem, "test text");
5511         test_node_get_value_str((IUnknown*)node, "text test");
5512
5513         IHTMLDOMNode_Release(node);
5514     }
5515
5516     child_col = get_child_nodes((IUnknown*)elem);
5517     ok(child_col != NULL, "child_coll == NULL\n");
5518     if(child_col) {
5519         LONG length = 0;
5520
5521         test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]");
5522
5523         hres = IHTMLDOMChildrenCollection_get_length(child_col, &length);
5524         ok(hres == S_OK, "get_length failed: %08x\n", hres);
5525         ok(length, "length=0\n");
5526
5527         node2 = NULL;
5528         node = get_child_item(child_col, 0);
5529         ok(node != NULL, "node == NULL\n");
5530         if(node) {
5531             type = get_node_type((IUnknown*)node);
5532             ok(type == 3, "type=%d\n", type);
5533             node2 = node_get_next((IUnknown*)node);
5534             IHTMLDOMNode_Release(node);
5535         }
5536
5537         node = get_child_item(child_col, 1);
5538         ok(node != NULL, "node == NULL\n");
5539         if(node) {
5540             type = get_node_type((IUnknown*)node);
5541             ok(type == 8, "type=%d\n", type);
5542
5543             test_elem_id((IUnknown*)node, NULL);
5544             ok(iface_cmp((IUnknown*)node2, (IUnknown*)node), "node2 != node\n");
5545             IHTMLDOMNode_Release(node2);
5546             IHTMLDOMNode_Release(node);
5547         }
5548
5549         hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL);
5550         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
5551
5552         hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL);
5553         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
5554
5555         hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp);
5556         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5557
5558         hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp);
5559         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5560
5561         test_child_col_disp(child_col);
5562
5563         IHTMLDOMChildrenCollection_Release(child_col);
5564     }
5565
5566     test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
5567     test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
5568     test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
5569
5570     IHTMLElement_Release(elem);
5571
5572     test_stylesheets(doc);
5573     test_create_option_elem(doc);
5574     test_create_img_elem(doc);
5575
5576     elem = get_doc_elem_by_id(doc, "tbl");
5577     ok(elem != NULL, "elem = NULL\n");
5578     test_elem_set_innertext(elem, "inner text");
5579     IHTMLElement_Release(elem);
5580
5581     test_doc_title(doc, "test");
5582     test_doc_set_title(doc, "test title");
5583     test_doc_title(doc, "test title");
5584
5585     disp = NULL;
5586     hres = IHTMLDocument2_get_Script(doc, &disp);
5587     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
5588     if(hres == S_OK)
5589     {
5590         IDispatchEx *dispex;
5591         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
5592         ok(hres == S_OK, "IDispatch_QueryInterface failed: %08x\n", hres);
5593         if(hres == S_OK)
5594         {
5595             DISPID pid = -1;
5596             BSTR str = a2bstr("Testing");
5597             hres = IDispatchEx_GetDispID(dispex, str, 1, &pid);
5598             ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5599             ok(pid != -1, "pid == -1\n");
5600             SysFreeString(str);
5601             IDispatchEx_Release(dispex);
5602         }
5603     }
5604     IDispatch_Release(disp);
5605
5606     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
5607     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
5608
5609     str = a2bstr("img");
5610     hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col);
5611     ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres);
5612     SysFreeString(str);
5613     if(hres == S_OK)
5614     {
5615         static const elem_type_t img_types[] = { ET_IMG };
5616
5617         test_elem_collection((IUnknown*)col, img_types, sizeof(img_types)/sizeof(img_types[0]));
5618         IHTMLElementCollection_Release(col);
5619     }
5620
5621     elem = get_doc_elem_by_id(doc, "y");
5622     test_elem_set_innerhtml((IUnknown*)elem, "inner html");
5623     test_elem_innerhtml((IUnknown*)elem, "inner html");
5624     test_elem_set_innerhtml((IUnknown*)elem, "");
5625     test_elem_innerhtml((IUnknown*)elem, NULL);
5626     node = node_get_next((IUnknown*)elem);
5627     ok(!node, "node = %p\n", node);
5628
5629     elem2 = get_doc_elem_by_id(doc, "x");
5630     test_elem_tag((IUnknown*)elem2, "A");
5631     node = node_get_next((IUnknown*)elem2);
5632     IHTMLDOMNode_Release(node);
5633     IHTMLElement_Release(elem2);
5634     IHTMLElement_Release(elem);
5635
5636     IHTMLDocument3_Release(doc3);
5637
5638     window = get_doc_window(doc);
5639     test_window_name(window, NULL);
5640     set_window_name(window, "test name");
5641     test_window_length(window, 1);
5642     IHTMLWindow2_Release(window);
5643 }
5644
5645 static void test_elems2(IHTMLDocument2 *doc)
5646 {
5647     IHTMLElement *elem, *elem2;
5648
5649     static const elem_type_t outer_types[] = {
5650         ET_BR,
5651         ET_A
5652     };
5653
5654     elem = get_doc_elem_by_id(doc, "divid");
5655
5656     test_elem_set_innerhtml((IUnknown*)elem, "<div id=\"innerid\"></div>");
5657     elem2 = get_doc_elem_by_id(doc, "innerid");
5658     ok(elem2 != NULL, "elem2 == NULL\n");
5659     test_elem_set_outerhtml((IUnknown*)elem2, "<br><a href=\"about:blank\" id=\"aid\">a</a>");
5660     test_elem_all((IUnknown*)elem, outer_types, sizeof(outer_types)/sizeof(*outer_types));
5661     IHTMLElement_Release(elem2);
5662
5663     elem2 = get_doc_elem_by_id(doc, "aid");
5664     ok(elem2 != NULL, "elem2 == NULL\n");
5665     test_elem_set_outerhtml((IUnknown*)elem2, "");
5666     test_elem_all((IUnknown*)elem, outer_types, 1);
5667     IHTMLElement_Release(elem2);
5668
5669     IHTMLElement_Release(elem);
5670 }
5671
5672 static void test_create_elems(IHTMLDocument2 *doc)
5673 {
5674     IHTMLElement *elem, *body, *elem2;
5675     IHTMLDOMNode *node, *node2, *node3, *comment;
5676     IHTMLDocument5 *doc5;
5677     IDispatch *disp;
5678     VARIANT var;
5679     LONG type;
5680     HRESULT hres;
5681     BSTR str;
5682
5683     static const elem_type_t types1[] = { ET_TESTG };
5684
5685     elem = test_create_elem(doc, "TEST");
5686     test_elem_tag((IUnknown*)elem, "TEST");
5687     type = get_node_type((IUnknown*)elem);
5688     ok(type == 1, "type=%d\n", type);
5689     test_ifaces((IUnknown*)elem, elem_iids);
5690     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
5691
5692     hres = IHTMLDocument2_get_body(doc, &body);
5693     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5694     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
5695
5696     node = test_node_append_child((IUnknown*)body, (IUnknown*)elem);
5697     test_node_has_child((IUnknown*)body, VARIANT_TRUE);
5698     elem2 = get_elem_iface((IUnknown*)node);
5699     IHTMLElement_Release(elem2);
5700
5701     hres = IHTMLElement_get_all(body, &disp);
5702     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5703     test_elem_collection((IUnknown*)disp, types1, sizeof(types1)/sizeof(types1[0]));
5704     IDispatch_Release(disp);
5705
5706     test_node_remove_child((IUnknown*)body, node);
5707
5708     hres = IHTMLElement_get_all(body, &disp);
5709     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5710     test_elem_collection((IUnknown*)disp, NULL, 0);
5711     IDispatch_Release(disp);
5712     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
5713
5714     IHTMLElement_Release(elem);
5715     IHTMLDOMNode_Release(node);
5716
5717     node = test_create_text(doc, "test");
5718     test_ifaces((IUnknown*)node, text_iids);
5719     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
5720
5721     V_VT(&var) = VT_NULL;
5722     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
5723     IHTMLDOMNode_Release(node);
5724
5725     node = test_create_text(doc, "insert ");
5726
5727     V_VT(&var) = VT_DISPATCH;
5728     V_DISPATCH(&var) = (IDispatch*)node2;
5729     node3 = test_node_insertbefore((IUnknown*)body, node, &var);
5730     IHTMLDOMNode_Release(node);
5731     IHTMLDOMNode_Release(node2);
5732     IHTMLDOMNode_Release(node3);
5733
5734     test_elem_innertext(body, "insert test");
5735     test_elem_innerhtml((IUnknown*)body, "insert test");
5736
5737     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
5738     if(hres == S_OK)
5739     {
5740         str = a2bstr("testing");
5741         hres = IHTMLDocument5_createComment(doc5, str, &comment);
5742         SysFreeString(str);
5743         ok(hres == S_OK, "createComment failed: %08x\n", hres);
5744         if(hres == S_OK)
5745         {
5746             type = get_node_type((IUnknown*)comment);
5747             ok(type == 8, "type=%d, expected 8\n", type);
5748
5749             test_node_get_value_str((IUnknown*)comment, "testing");
5750
5751             IHTMLDOMNode_Release(comment);
5752         }
5753
5754         IHTMLDocument5_Release(doc5);
5755     }
5756
5757     IHTMLElement_Release(body);
5758 }
5759
5760 static void test_exec(IUnknown *unk, const GUID *grpid, DWORD cmdid, VARIANT *in, VARIANT *out)
5761 {
5762     IOleCommandTarget *cmdtrg;
5763     HRESULT hres;
5764
5765     hres = IHTMLTxtRange_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
5766     ok(hres == S_OK, "Could not get IOleCommandTarget interface: %08x\n", hres);
5767
5768     hres = IOleCommandTarget_Exec(cmdtrg, grpid, cmdid, 0, in, out);
5769     ok(hres == S_OK, "Exec failed: %08x\n", hres);
5770
5771     IOleCommandTarget_Release(cmdtrg);
5772 }
5773
5774 static void test_indent(IHTMLDocument2 *doc)
5775 {
5776     IHTMLElementCollection *col;
5777     IHTMLTxtRange *range;
5778     HRESULT hres;
5779
5780     static const elem_type_t all_types[] = {
5781         ET_HTML,
5782         ET_HEAD,
5783         ET_TITLE,
5784         ET_BODY,
5785         ET_BR,
5786         ET_A,
5787     };
5788
5789     static const elem_type_t indent_types[] = {
5790         ET_HTML,
5791         ET_HEAD,
5792         ET_TITLE,
5793         ET_BODY,
5794         ET_BLOCKQUOTE,
5795         ET_P,
5796         ET_BR,
5797         ET_A,
5798     };
5799
5800     hres = IHTMLDocument2_get_all(doc, &col);
5801     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5802     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5803     IHTMLElementCollection_Release(col);
5804
5805     range = test_create_body_range(doc);
5806     test_exec((IUnknown*)range, &CGID_MSHTML, IDM_INDENT, NULL, NULL);
5807     IHTMLTxtRange_Release(range);
5808
5809     hres = IHTMLDocument2_get_all(doc, &col);
5810     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5811     test_elem_collection((IUnknown*)col, indent_types, sizeof(indent_types)/sizeof(indent_types[0]));
5812     IHTMLElementCollection_Release(col);
5813 }
5814
5815 static void test_cond_comment(IHTMLDocument2 *doc)
5816 {
5817     IHTMLElementCollection *col;
5818     HRESULT hres;
5819
5820     static const elem_type_t all_types[] = {
5821         ET_HTML,
5822         ET_HEAD,
5823         ET_TITLE,
5824         ET_BODY,
5825         ET_BR
5826     };
5827
5828     hres = IHTMLDocument2_get_all(doc, &col);
5829     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5830     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5831     IHTMLElementCollection_Release(col);
5832 }
5833
5834 static void test_frame(IDispatch *disp, const char *exp_id)
5835 {
5836     IHTMLWindow2 *frame2, *parent, *top;
5837     IHTMLDocument2 *parent_doc, *top_doc;
5838     IHTMLWindow4 *frame;
5839     IHTMLFrameBase *frame_elem;
5840     HRESULT hres;
5841
5842     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame);
5843     ok(hres == S_OK, "Could not get IHTMLWindow4 interface: 0x%08x\n", hres);
5844     if(FAILED(hres))
5845         return;
5846
5847     hres = IHTMLWindow4_get_frameElement(frame, &frame_elem);
5848     ok(hres == S_OK, "IHTMLWindow4_get_frameElement failed: 0x%08x\n", hres);
5849     IHTMLWindow4_Release(frame);
5850     if(FAILED(hres))
5851         return;
5852
5853     test_frame_doc((IUnknown*)frame_elem);
5854     test_elem_id((IUnknown*)frame_elem, exp_id);
5855     IHTMLElement_Release(frame_elem);
5856
5857     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow2, (void**)&frame2);
5858     ok(hres == S_OK, "Could not get IHTMLWindow2 interface: 0x%08x\n", hres);
5859     if(FAILED(hres))
5860         return;
5861
5862     hres = IHTMLWindow2_get_parent(frame2, &parent);
5863     ok(hres == S_OK, "IHTMLWindow2_get_parent failed: 0x%08x\n", hres);
5864     if(FAILED(hres)){
5865         IHTMLWindow2_Release(frame2);
5866         return;
5867     }
5868
5869     hres = IHTMLWindow2_get_document(parent, &parent_doc);
5870     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
5871     IHTMLWindow2_Release(parent);
5872     if(FAILED(hres)){
5873         IHTMLWindow2_Release(frame2);
5874         return;
5875     }
5876
5877     test_doc_title(parent_doc, "frameset test");
5878     IHTMLDocument2_Release(parent_doc);
5879
5880     /* test get_top */
5881     hres = IHTMLWindow2_get_top(frame2, &top);
5882     ok(hres == S_OK, "IHTMLWindow2_get_top failed: 0x%08x\n", hres);
5883     IHTMLWindow2_Release(frame2);
5884     if(FAILED(hres))
5885         return;
5886
5887     hres = IHTMLWindow2_get_document(top, &top_doc);
5888     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
5889     IHTMLWindow2_Release(top);
5890     if(FAILED(hres))
5891         return;
5892
5893     test_doc_title(top_doc, "frameset test");
5894     IHTMLDocument2_Release(top_doc);
5895 }
5896
5897 static void test_frameset(IHTMLDocument2 *doc)
5898 {
5899     IHTMLWindow2 *window;
5900     IHTMLFramesCollection2 *frames;
5901     IHTMLElement *elem;
5902     LONG length;
5903     VARIANT index_var, result_var;
5904     HRESULT hres;
5905
5906     window = get_doc_window(doc);
5907
5908     /* test using IHTMLFramesCollection object */
5909
5910     hres = IHTMLWindow2_get_frames(window, &frames);
5911     ok(hres == S_OK, "IHTMLWindow2_get_frames failed: 0x%08x\n", hres);
5912     IHTMLWindow2_Release(window);
5913     if(FAILED(hres))
5914         return;
5915
5916     /* test result length */
5917     hres = IHTMLFramesCollection2_get_length(frames, &length);
5918     ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres);
5919     ok(length == 2, "IHTMLFramesCollection2_get_length should have been 2, was: %d\n", length);
5920
5921     /* test first frame */
5922     V_VT(&index_var) = VT_I4;
5923     V_I4(&index_var) = 0;
5924     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
5925     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
5926     if(SUCCEEDED(hres)) {
5927         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
5928         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
5929     }
5930     VariantClear(&result_var);
5931
5932     /* test second frame */
5933     V_I4(&index_var) = 1;
5934     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
5935     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
5936     if(SUCCEEDED(hres)) {
5937         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
5938         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
5939     }
5940     VariantClear(&result_var);
5941
5942     /* fail on third frame */
5943     V_I4(&index_var) = 2;
5944     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
5945     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have"
5946            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
5947     VariantClear(&result_var);
5948
5949     /* string argument (element id lookup) */
5950     V_VT(&index_var) = VT_BSTR;
5951     V_BSTR(&index_var) = a2bstr("fr1");
5952     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
5953     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
5954     if(SUCCEEDED(hres)) {
5955         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
5956         test_frame(V_DISPATCH(&result_var), "fr1");
5957     }
5958     VariantClear(&result_var);
5959     VariantClear(&index_var);
5960
5961     /* invalid argument */
5962     V_VT(&index_var) = VT_BOOL;
5963     V_BOOL(&index_var) = VARIANT_TRUE;
5964     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
5965     ok(hres == E_INVALIDARG, "IHTMLFramesCollection2_item should have"
5966            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
5967     VariantClear(&result_var);
5968
5969     IHTMLFramesCollection2_Release(frames);
5970
5971     /* test using IHTMLWindow2 inheritance */
5972
5973     /* test result length */
5974     hres = IHTMLWindow2_get_length(window, &length);
5975     ok(hres == S_OK, "IHTMLWindow2_get_length failed: 0x%08x\n", hres);
5976     ok(length == 2, "IHTMLWindow2_get_length should have been 2, was: %d\n", length);
5977
5978     /* test first frame */
5979     V_VT(&index_var) = VT_I4;
5980     V_I4(&index_var) = 0;
5981     hres = IHTMLWindow2_item(window, &index_var, &result_var);
5982     ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
5983     if(SUCCEEDED(hres)) {
5984         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
5985         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
5986     }
5987     VariantClear(&result_var);
5988
5989     /* test second frame */
5990     V_I4(&index_var) = 1;
5991     hres = IHTMLWindow2_item(window, &index_var, &result_var);
5992     ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
5993     if(SUCCEEDED(hres)) {
5994         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
5995         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
5996     }
5997     VariantClear(&result_var);
5998
5999     /* fail on third frame */
6000     V_I4(&index_var) = 2;
6001     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6002     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLWindow2_item should have"
6003            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
6004     VariantClear(&result_var);
6005
6006     /* string argument (element id lookup) */
6007     V_VT(&index_var) = VT_BSTR;
6008     V_BSTR(&index_var) = a2bstr("fr2");
6009     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6010     ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
6011     if(SUCCEEDED(hres)) {
6012         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6013         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
6014     }
6015     VariantClear(&result_var);
6016     VariantClear(&index_var);
6017
6018     /* invalid argument */
6019     V_VT(&index_var) = VT_BOOL;
6020     V_BOOL(&index_var) = VARIANT_TRUE;
6021     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6022     ok(hres == E_INVALIDARG, "IHTMLWindow2_item should have"
6023            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
6024     VariantClear(&result_var);
6025
6026     /* getElementById with node name attributes */
6027     elem = get_doc_elem_by_id(doc, "nm1");
6028     test_elem_id((IUnknown*)elem, "fr1");
6029     IHTMLElement_Release(elem);
6030 }
6031
6032 static IHTMLDocument2 *notif_doc;
6033 static BOOL doc_complete;
6034
6035 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
6036         REFIID riid, void**ppv)
6037 {
6038     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
6039         *ppv = iface;
6040         return S_OK;
6041     }
6042
6043     ok(0, "unexpected call\n");
6044     return E_NOINTERFACE;
6045 }
6046
6047 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
6048 {
6049     return 2;
6050 }
6051
6052 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
6053 {
6054     return 1;
6055 }
6056
6057 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
6058 {
6059     if(dispID == DISPID_READYSTATE){
6060         BSTR state;
6061         HRESULT hres;
6062
6063         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
6064         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
6065
6066         if(!strcmp_wa(state, "complete"))
6067             doc_complete = TRUE;
6068
6069         SysFreeString(state);
6070     }
6071
6072     return S_OK;
6073 }
6074
6075 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
6076 {
6077     ok(0, "unexpected call\n");
6078     return E_NOTIMPL;
6079 }
6080
6081 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
6082     PropertyNotifySink_QueryInterface,
6083     PropertyNotifySink_AddRef,
6084     PropertyNotifySink_Release,
6085     PropertyNotifySink_OnChanged,
6086     PropertyNotifySink_OnRequestEdit
6087 };
6088
6089 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
6090
6091 static IHTMLDocument2 *create_doc_with_string(const char *str)
6092 {
6093     IPersistStreamInit *init;
6094     IStream *stream;
6095     IHTMLDocument2 *doc;
6096     HGLOBAL mem;
6097     SIZE_T len;
6098
6099     notif_doc = doc = create_document();
6100     if(!doc)
6101         return NULL;
6102
6103     doc_complete = FALSE;
6104     len = strlen(str);
6105     mem = GlobalAlloc(0, len);
6106     memcpy(mem, str, len);
6107     CreateStreamOnHGlobal(mem, TRUE, &stream);
6108
6109     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
6110
6111     IPersistStreamInit_Load(init, stream);
6112     IPersistStreamInit_Release(init);
6113     IStream_Release(stream);
6114
6115     return doc;
6116 }
6117
6118 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
6119 {
6120     IConnectionPointContainer *container;
6121     IConnectionPoint *cp;
6122     DWORD cookie;
6123     HRESULT hres;
6124
6125     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
6126     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
6127
6128     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
6129     IConnectionPointContainer_Release(container);
6130     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
6131
6132     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
6133     IConnectionPoint_Release(cp);
6134     ok(hres == S_OK, "Advise failed: %08x\n", hres);
6135 }
6136
6137 typedef void (*domtest_t)(IHTMLDocument2*);
6138
6139 static void run_domtest(const char *str, domtest_t test)
6140 {
6141     IHTMLDocument2 *doc;
6142     ULONG ref;
6143     MSG msg;
6144
6145     doc = create_doc_with_string(str);
6146     if(!doc)
6147         return;
6148
6149     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
6150
6151     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
6152         TranslateMessage(&msg);
6153         DispatchMessage(&msg);
6154     }
6155
6156     test(doc);
6157
6158     ref = IHTMLDocument2_Release(doc);
6159     ok(!ref ||
6160        ref == 1, /* Vista */
6161        "ref = %d\n", ref);
6162 }
6163
6164 START_TEST(dom)
6165 {
6166     CoInitialize(NULL);
6167
6168     run_domtest(doc_str1, test_doc_elem);
6169     run_domtest(doc_str1, test_get_set_attr);
6170     run_domtest(range_test_str, test_txtrange);
6171     run_domtest(range_test2_str, test_txtrange2);
6172     if (winetest_interactive || ! is_ie_hardened()) {
6173         run_domtest(elem_test_str, test_elems);
6174     }else {
6175         skip("IE running in Enhanced Security Configuration\n");
6176     }
6177     run_domtest(elem_test2_str, test_elems2);
6178     run_domtest(doc_blank, test_create_elems);
6179     run_domtest(doc_blank, test_defaults);
6180     run_domtest(indent_test_str, test_indent);
6181     run_domtest(cond_comment_str, test_cond_comment);
6182     run_domtest(frameset_str, test_frameset);
6183
6184     CoUninitialize();
6185 }