mshtml: Support IObjectIdentity interface in HTMLWindow object.
[wine] / dlls / mshtml / tests / dom.c
1 /*
2  * Copyright 2007-2011 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 #include "objsafe.h"
36 #include "htiface.h"
37 #include "tlogstg.h"
38
39 static INT (WINAPI *pLCIDToLocaleName)(LCID,LPWSTR,INT,DWORD);
40 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void);
41
42 static const char doc_blank[] = "<html></html>";
43 static const char doc_str1[] = "<html><body>test</body></html>";
44 static const char range_test_str[] =
45     "<html><body>test \na<font size=\"2\">bc\t123<br /> it's\r\n  \t</font>text<br /></body></html>";
46 static const char range_test2_str[] =
47     "<html><body>abc<hr />123<br /><hr />def</body></html>";
48 static const char elem_test_str[] =
49     "<html><head><title>test</title><style id=\"styleid\">.body { margin-right: 0px; }</style>"
50     "<meta id=\"metaid\" name=\"meta name\" http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
51     "<link id=\"linkid\"></head>"
52     "<body onload=\"Testing()\">text test<!-- a comment -->"
53     "<a id=\"a\" href=\"http://test\" name=\"x\">link</a>"
54     "<label for=\"in\" id=\"labelid\">Label:</label>"
55     "<input id=\"in\" class=\"testclass\" tabIndex=\"2\" title=\"test title\" />"
56     "<button id=\"btnid\"></button>"
57     "<select id=\"s\"><option id=\"x\" value=\"val1\">opt1</option><option id=\"y\">opt2</option></select>"
58     "<textarea id=\"X\">text text</textarea>"
59     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td>td1 text</td><td>td2 text</td></tr></tbody></table>"
60     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
61     "<test /><object id=\"objid\" name=\"objname\" vspace=100></object><embed />"
62     "<img id=\"imgid\" name=\"WineImg\"/>"
63     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
64     "<form id=\"frm\"></form>"
65     "<div id=\"attr\" attr1=\"attr1\" attr2 attr3=\"attr3\"></div>"
66     "</body></html>";
67 static const char elem_test2_str[] =
68     "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
69     "<link id=\"linkid\" rel=\"stylesheet\" href=\"about:blank\" type=\"text/css\"></head>"
70     "<body><div id=\"divid\" emptyattr=\"\" onclick=\"parseInt();\"></div></body>"
71     "</html>";
72
73 static const char indent_test_str[] =
74     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
75 static const char cond_comment_str[] =
76     "<html><head><title>test</title></head><body>"
77     "<!--[if gte IE 4]> <br> <![endif]-->"
78     "</body></html>";
79 static const char frameset_str[] =
80     "<html><head><title>frameset test</title></head><frameset rows=\"25, 25, *\">"
81     "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
82     "<frame src=\"about:blank\" id=\"fr3\">"
83     "</frameset></html>";
84 static const char emptydiv_str[] =
85     "<html><head><title>emptydiv test</title></head>"
86     "<body><div id=\"divid\"></div></body></html>";
87 static const char noscript_str[] =
88     "<html><head><title>noscript test</title><noscript><style>.body { margin-right: 0px; }</style></noscript></head>"
89     "<body><noscript><div>test</div></noscript></body></html>";
90 static const char doctype_str[] =
91     "<!DOCTYPE html>"
92     "<html><head><title>emptydiv test</title></head>"
93     "<body><div id=\"divid\"></div></body></html>";
94
95 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
96 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
97 static WCHAR wordW[] = {'w','o','r','d',0};
98
99 typedef enum {
100     ET_NONE,
101     ET_HTML,
102     ET_HEAD,
103     ET_TITLE,
104     ET_BODY,
105     ET_A,
106     ET_INPUT,
107     ET_SELECT,
108     ET_TEXTAREA,
109     ET_OPTION,
110     ET_STYLE,
111     ET_BLOCKQUOTE,
112     ET_P,
113     ET_BR,
114     ET_TABLE,
115     ET_TBODY,
116     ET_SCRIPT,
117     ET_TEST,
118     ET_TESTG,
119     ET_COMMENT,
120     ET_IMG,
121     ET_TR,
122     ET_TD,
123     ET_IFRAME,
124     ET_FORM,
125     ET_FRAME,
126     ET_OBJECT,
127     ET_EMBED,
128     ET_DIV,
129     ET_META,
130     ET_NOSCRIPT,
131     ET_LINK,
132     ET_LABEL,
133     ET_BUTTON
134 } elem_type_t;
135
136 static const IID * const none_iids[] = {
137     &IID_IUnknown,
138     NULL
139 };
140
141 static const IID * const doc_node_iids[] = {
142     &IID_IHTMLDOMNode,
143     &IID_IHTMLDOMNode2,
144     &IID_IHTMLDocument,
145     &IID_IHTMLDocument2,
146     &IID_IHTMLDocument3,
147     &IID_IHTMLDocument4,
148     &IID_IHTMLDocument5,
149     &IID_IDispatchEx,
150     &IID_IConnectionPointContainer,
151     &IID_IInternetHostSecurityManager,
152     &IID_IOleContainer,
153     &IID_IObjectSafety,
154     &IID_IProvideClassInfo,
155     NULL
156 };
157
158 static const IID * const doc_obj_iids[] = {
159     &IID_IHTMLDocument,
160     &IID_IHTMLDocument2,
161     &IID_IHTMLDocument3,
162     &IID_IHTMLDocument4,
163     &IID_IHTMLDocument5,
164     &IID_IDispatchEx,
165     &IID_IConnectionPointContainer,
166     &IID_ICustomDoc,
167     &IID_IOleContainer,
168     &IID_IObjectSafety,
169     &IID_IProvideClassInfo,
170     &IID_ITargetContainer,
171     NULL
172 };
173
174 #define ELEM_IFACES \
175     &IID_IHTMLDOMNode,  \
176     &IID_IHTMLDOMNode2, \
177     &IID_IHTMLElement,  \
178     &IID_IHTMLElement2, \
179     &IID_IHTMLElement3, \
180     &IID_IHTMLElement4, \
181     &IID_IDispatchEx
182
183 static const IID * const elem_iids[] = {
184     ELEM_IFACES,
185     &IID_IConnectionPointContainer,
186     NULL
187 };
188
189 static const IID * const body_iids[] = {
190     ELEM_IFACES,
191     &IID_IHTMLTextContainer,
192     &IID_IHTMLBodyElement,
193     &IID_IConnectionPointContainer,
194     NULL
195 };
196
197 static const IID * const anchor_iids[] = {
198     ELEM_IFACES,
199     &IID_IHTMLAnchorElement,
200     &IID_IConnectionPointContainer,
201     NULL
202 };
203
204 static const IID * const input_iids[] = {
205     ELEM_IFACES,
206     &IID_IHTMLInputElement,
207     &IID_IHTMLInputTextElement,
208     &IID_IConnectionPointContainer,
209     NULL
210 };
211
212 static const IID *const button_iids[] = {
213     ELEM_IFACES,
214     &IID_IHTMLButtonElement,
215     &IID_IConnectionPointContainer,
216     NULL
217 };
218
219 static const IID * const label_iids[] = {
220     ELEM_IFACES,
221     &IID_IHTMLLabelElement,
222     &IID_IConnectionPointContainer,
223     NULL
224 };
225
226 static const IID * const select_iids[] = {
227     ELEM_IFACES,
228     &IID_IHTMLSelectElement,
229     &IID_IConnectionPointContainer,
230     NULL
231 };
232
233 static const IID * const textarea_iids[] = {
234     ELEM_IFACES,
235     &IID_IHTMLTextAreaElement,
236     &IID_IConnectionPointContainer,
237     NULL
238 };
239
240 static const IID * const option_iids[] = {
241     ELEM_IFACES,
242     &IID_IHTMLOptionElement,
243     &IID_IConnectionPointContainer,
244     NULL
245 };
246
247 static const IID * const table_iids[] = {
248     ELEM_IFACES,
249     &IID_IHTMLTable,
250     &IID_IHTMLTable2,
251     &IID_IHTMLTable3,
252     &IID_IConnectionPointContainer,
253     NULL
254 };
255
256 static const IID * const script_iids[] = {
257     ELEM_IFACES,
258     &IID_IHTMLScriptElement,
259     &IID_IConnectionPointContainer,
260     NULL
261 };
262
263 static const IID * const text_iids[] = {
264     &IID_IHTMLDOMNode,
265     &IID_IHTMLDOMNode2,
266     &IID_IHTMLDOMTextNode,
267     NULL
268 };
269
270 static const IID * const attr_iids[] = {
271     &IID_IHTMLDOMAttribute,
272     &IID_IDispatchEx,
273     NULL
274 };
275
276 static const IID * const location_iids[] = {
277     &IID_IDispatch,
278     &IID_IHTMLLocation,
279     NULL
280 };
281
282 static const IID * const window_iids[] = {
283     &IID_IDispatch,
284     &IID_IHTMLWindow2,
285     &IID_IHTMLWindow3,
286     &IID_IDispatchEx,
287     &IID_IServiceProvider,
288     NULL
289 };
290
291 static const IID * const comment_iids[] = {
292     ELEM_IFACES,
293     &IID_IHTMLCommentElement,
294     &IID_IConnectionPointContainer,
295     NULL
296 };
297
298 static const IID * const img_iids[] = {
299     ELEM_IFACES,
300     &IID_IHTMLImgElement,
301     &IID_IConnectionPointContainer,
302     NULL
303 };
304
305 static const IID * const tr_iids[] = {
306     ELEM_IFACES,
307     &IID_IHTMLTableRow,
308     &IID_IConnectionPointContainer,
309     NULL
310 };
311
312 static const IID * const td_iids[] = {
313     ELEM_IFACES,
314     &IID_IHTMLTableCell,
315     &IID_IConnectionPointContainer,
316     NULL
317 };
318
319 static const IID * const frame_iids[] = {
320     ELEM_IFACES,
321     &IID_IHTMLFrameBase,
322     &IID_IHTMLFrameBase2,
323     &IID_IConnectionPointContainer,
324     NULL
325 };
326
327 static const IID * const head_iids[] = {
328     ELEM_IFACES,
329     &IID_IHTMLHeadElement,
330     &IID_IConnectionPointContainer,
331     NULL
332 };
333
334 static const IID * const title_iids[] = {
335     ELEM_IFACES,
336     &IID_IHTMLTitleElement,
337     &IID_IConnectionPointContainer,
338     NULL
339 };
340
341 static const IID * const meta_iids[] = {
342     ELEM_IFACES,
343     &IID_IHTMLMetaElement,
344     &IID_IConnectionPointContainer,
345     NULL
346 };
347
348 static const IID * const link_iids[] = {
349     ELEM_IFACES,
350     &IID_IHTMLLinkElement,
351     &IID_IConnectionPointContainer,
352     NULL
353 };
354
355 static const IID * const object_iids[] = {
356     ELEM_IFACES,
357     &IID_IHTMLObjectElement,
358     &IID_IHTMLObjectElement2,
359     /* FIXME: No IConnectionPointContainer */
360     NULL
361 };
362
363 static const IID * const embed_iids[] = {
364     ELEM_IFACES,
365     &IID_IHTMLEmbedElement,
366     /* FIXME: No IConnectionPointContainer */
367     NULL
368 };
369
370 static const IID * const iframe_iids[] = {
371     ELEM_IFACES,
372     &IID_IHTMLFrameBase,
373     &IID_IHTMLFrameBase2,
374     &IID_IHTMLIFrameElement,
375     &IID_IHTMLIFrameElement2,
376     &IID_IConnectionPointContainer,
377     NULL
378 };
379
380 static const IID * const form_iids[] = {
381     ELEM_IFACES,
382     &IID_IHTMLFormElement,
383     &IID_IConnectionPointContainer,
384     NULL
385 };
386
387 static const IID * const styleelem_iids[] = {
388     ELEM_IFACES,
389     &IID_IHTMLStyleElement,
390     &IID_IConnectionPointContainer,
391     NULL
392 };
393
394 static const IID * const generic_iids[] = {
395     ELEM_IFACES,
396     &IID_IHTMLGenericElement,
397     &IID_IConnectionPointContainer,
398     NULL
399 };
400
401 static const IID * const style_iids[] = {
402     &IID_IUnknown,
403     &IID_IDispatch,
404     &IID_IDispatchEx,
405     &IID_IHTMLStyle,
406     &IID_IHTMLStyle2,
407     &IID_IHTMLStyle3,
408     &IID_IHTMLStyle4,
409     NULL
410 };
411
412 static const IID * const cstyle_iids[] = {
413     &IID_IUnknown,
414     &IID_IDispatch,
415     &IID_IDispatchEx,
416     &IID_IHTMLCurrentStyle,
417     &IID_IHTMLCurrentStyle2,
418     &IID_IHTMLCurrentStyle3,
419     NULL
420 };
421
422 static const IID * const img_factory_iids[] = {
423     &IID_IUnknown,
424     &IID_IDispatch,
425     &IID_IDispatchEx,
426     &IID_IHTMLImageElementFactory,
427     NULL
428 };
429
430 typedef struct {
431     const char *tag;
432     REFIID *iids;
433     const IID *dispiid;
434 } elem_type_info_t;
435
436 static const elem_type_info_t elem_type_infos[] = {
437     {"",          none_iids,        NULL},
438     {"HTML",      elem_iids,        NULL},
439     {"HEAD",      head_iids,        &DIID_DispHTMLHeadElement},
440     {"TITLE",     title_iids,       &DIID_DispHTMLTitleElement},
441     {"BODY",      body_iids,        &DIID_DispHTMLBody},
442     {"A",         anchor_iids,      &DIID_DispHTMLAnchorElement},
443     {"INPUT",     input_iids,       &DIID_DispHTMLInputElement},
444     {"SELECT",    select_iids,      &DIID_DispHTMLSelectElement},
445     {"TEXTAREA",  textarea_iids,    &DIID_DispHTMLTextAreaElement},
446     {"OPTION",    option_iids,      &DIID_DispHTMLOptionElement},
447     {"STYLE",     styleelem_iids,   &DIID_DispHTMLStyleElement},
448     {"BLOCKQUOTE",elem_iids,        NULL},
449     {"P",         elem_iids,        NULL},
450     {"BR",        elem_iids,        NULL},
451     {"TABLE",     table_iids,       &DIID_DispHTMLTable},
452     {"TBODY",     elem_iids,        NULL},
453     {"SCRIPT",    script_iids,      &DIID_DispHTMLScriptElement},
454     {"TEST",      elem_iids,        &DIID_DispHTMLUnknownElement},
455     {"TEST",      generic_iids,     &DIID_DispHTMLGenericElement},
456     {"!",         comment_iids,     &DIID_DispHTMLCommentElement},
457     {"IMG",       img_iids,         &DIID_DispHTMLImg},
458     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
459     {"TD",        td_iids,          &DIID_DispHTMLTableCell},
460     {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame},
461     {"FORM",      form_iids,        &DIID_DispHTMLFormElement},
462     {"FRAME",     frame_iids,       &DIID_DispHTMLFrameElement},
463     {"OBJECT",    object_iids,      &DIID_DispHTMLObjectElement},
464     {"EMBED",     embed_iids,       &DIID_DispHTMLEmbed},
465     {"DIV",       elem_iids,        NULL},
466     {"META",      meta_iids,        &DIID_DispHTMLMetaElement},
467     {"NOSCRIPT",  elem_iids,        NULL /*&DIID_DispHTMLNoShowElement*/},
468     {"LINK",      link_iids,        &DIID_DispHTMLLinkElement},
469     {"LABEL",     label_iids,       &DIID_DispHTMLLabelElement},
470     {"BUTTON",    button_iids,      &DIID_DispHTMLButtonElement}
471 };
472
473 static const char *dbgstr_guid(REFIID riid)
474 {
475     static char buf[50];
476
477     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
478             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
479             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
480             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
481
482     return buf;
483 }
484
485 static int strcmp_wa(LPCWSTR strw, const char *stra)
486 {
487     CHAR buf[512];
488     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
489     return lstrcmpA(stra, buf);
490 }
491
492 static BSTR a2bstr(const char *str)
493 {
494     BSTR ret;
495     int len;
496
497     if(!str)
498         return NULL;
499
500     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
501     ret = SysAllocStringLen(NULL, len);
502     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
503
504     return ret;
505 }
506
507 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
508 {
509     IUnknown *unk1, *unk2;
510
511     if(iface1 == iface2)
512         return TRUE;
513
514     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
515     IUnknown_Release(unk1);
516     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
517     IUnknown_Release(unk2);
518
519     return unk1 == unk2;
520 }
521
522 static IHTMLDocument2 *create_document(void)
523 {
524     IHTMLDocument2 *doc;
525     IHTMLDocument5 *doc5;
526     HRESULT hres;
527
528     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
529             &IID_IHTMLDocument2, (void**)&doc);
530     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
531     if(FAILED(hres))
532         return NULL;
533
534     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
535     if(FAILED(hres)) {
536         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
537         IHTMLDocument2_Release(doc);
538         return NULL;
539     }
540
541     IHTMLDocument5_Release(doc5);
542     return doc;
543 }
544
545 #define get_dispex_iface(u) _get_dispex_iface(__LINE__,u)
546 static IDispatchEx *_get_dispex_iface(unsigned line, IUnknown *unk)
547 {
548     IDispatchEx *dispex;
549     HRESULT hres;
550
551     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
552     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
553     return dispex;
554 }
555
556 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
557 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
558 {
559     const IID * const *piid;
560     IUnknown *unk;
561     HRESULT hres;
562
563      for(piid = iids; *piid; piid++) {
564         hres = IUnknown_QueryInterface(iface, *piid, (void**)&unk);
565         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", dbgstr_guid(*piid), hres);
566         if(SUCCEEDED(hres))
567             IUnknown_Release(unk);
568     }
569 }
570
571 #define test_no_iface(a,b) _test_no_iface(__LINE__,a,b)
572 static void _test_no_iface(unsigned line, IUnknown *iface, REFIID iid)
573 {
574     IUnknown *unk;
575     HRESULT hres;
576
577     unk = (void*)0xdeadbeef;
578     hres = IUnknown_QueryInterface(iface, iid, (void**)&unk);
579     ok_(__FILE__,line)(hres == E_NOINTERFACE, "hres = %08x, expected E_NOINTERFACE\n", hres);
580     ok_(__FILE__,line)(!unk, "unk = %p\n", unk);
581 }
582
583 #define test_get_dispid(u,id) _test_get_dispid(__LINE__,u,id)
584 static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
585 {
586     IDispatchEx *dispex = _get_dispex_iface(line, unk);
587     ITypeInfo *typeinfo;
588     BOOL ret = FALSE;
589     UINT ticnt;
590     HRESULT hres;
591
592     ticnt = 0xdeadbeef;
593     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
594     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
595     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
596
597     hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
598     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
599
600     if(SUCCEEDED(hres)) {
601         TYPEATTR *type_attr;
602
603         hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
604         ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
605         if(hres == S_OK) {
606             *iid = type_attr->guid;
607             ret = TRUE;
608         }
609
610         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
611         ITypeInfo_Release(typeinfo);
612     }
613
614     IDispatchEx_Release(dispex);
615     return ret;
616 }
617
618 #define test_disp_value(u) _test_disp_value(__LINE__,u,v)
619 static void _test_disp_value(unsigned line, IUnknown *unk, const char *val)
620 {
621     IDispatchEx *dispex = _get_dispex_iface(line, unk);
622     DISPPARAMS dp  = {NULL,NULL,0,0};
623     EXCEPINFO ei;
624     VARIANT var;
625     HRESULT hres;
626
627     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
628     IDispatchEx_Release(dispex);
629     ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres);
630
631     ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var));
632     ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val);
633     VariantClear(&var);
634 }
635
636 #define test_disp(u,id,v) _test_disp(__LINE__,u,id,v)
637 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val)
638 {
639     IID iid;
640
641     if(_test_get_dispid(line, unk, &iid))
642         ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", dbgstr_guid(&iid));
643
644     if(val)
645         _test_disp_value(line, unk, val);
646 }
647
648 #define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v)
649 static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val)
650 {
651     IID iid;
652
653     if(_test_get_dispid(line, unk, &iid))
654         ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)),
655                 "unexpected guid %s\n", dbgstr_guid(&iid));
656
657     if(val)
658         _test_disp_value(line, unk, val);
659 }
660
661 #define test_class_info(u) _test_class_info(__LINE__,u)
662 static void _test_class_info(unsigned line, IUnknown *unk)
663 {
664     IProvideClassInfo *classinfo;
665     ITypeInfo *typeinfo;
666     TYPEATTR *type_attr;
667     HRESULT hres;
668
669     hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo, (void**)&classinfo);
670     ok_(__FILE__,line)(hres == S_OK, "Could not get IProvideClassInfo interface: %08x\n", hres);
671     if(FAILED(hres))
672         return;
673
674     hres = IProvideClassInfo_GetClassInfo(classinfo, &typeinfo);
675     ok_(__FILE__,line)(hres == S_OK, "Could not get ITypeInfo interface: %08x\n", hres);
676     if(FAILED(hres))
677     {
678         IProvideClassInfo_Release(classinfo);
679         return;
680     }
681
682     hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
683     ok_(__FILE__,line)(hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
684     if(SUCCEEDED(hres))
685     {
686         ok_(__FILE__,line)(IsEqualGUID(&type_attr->guid, &CLSID_HTMLDocument),
687                 "unexpected guid %s\n", dbgstr_guid(&type_attr->guid));
688         ok_(__FILE__,line)(type_attr->typekind == TKIND_COCLASS,
689                 "unexpected typekind %d\n", type_attr->typekind);
690         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
691     }
692
693     ITypeInfo_Release(typeinfo);
694     IProvideClassInfo_Release(classinfo);
695 }
696
697 #define set_dispex_value(a,b,c) _set_dispex_value(__LINE__,a,b,c)
698 static void _set_dispex_value(unsigned line, IUnknown *unk, const char *name, VARIANT *val)
699 {
700     IDispatchEx *dispex = _get_dispex_iface(line, unk);
701     DISPPARAMS dp = {val, NULL, 1, 0};
702     EXCEPINFO ei;
703     DISPID id;
704     BSTR str;
705     HRESULT hres;
706
707     str = a2bstr(name);
708     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure|fdexNameCaseInsensitive, &id);
709     SysFreeString(str);
710     ok_(__FILE__,line)(hres == S_OK, "GetDispID failed: %08x\n", hres);
711
712     memset(&ei, 0, sizeof(ei));
713     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
714     ok_(__FILE__,line)(hres == S_OK, "InvokeEx failed: %08x\n", hres);
715
716 }
717
718 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
719 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
720 {
721     IHTMLElement *elem;
722     HRESULT hres;
723
724     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
725     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres);
726     return elem;
727 }
728
729 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
730 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
731 {
732     IHTMLElement2 *elem;
733     HRESULT hres;
734
735     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem);
736     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres);
737     return elem;
738 }
739
740 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
741 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
742 {
743     IHTMLElement3 *elem;
744     HRESULT hres;
745
746     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem);
747     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres);
748     return elem;
749 }
750
751 #define get_elem4_iface(u) _get_elem4_iface(__LINE__,u)
752 static IHTMLElement4 *_get_elem4_iface(unsigned line, IUnknown *unk)
753 {
754     IHTMLElement4 *elem;
755     HRESULT hres;
756
757     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement4, (void**)&elem);
758     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement4: %08x\n", hres);
759     return elem;
760 }
761
762 #define get_node_iface(u) _get_node_iface(__LINE__,u)
763 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
764 {
765     IHTMLDOMNode *node;
766     HRESULT hres;
767
768     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node);
769     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres);
770     return node;
771 }
772
773 #define get_node2_iface(u) _get_node2_iface(__LINE__,u)
774 static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk)
775 {
776     IHTMLDOMNode2 *node;
777     HRESULT hres;
778
779     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node);
780     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres);
781     return node;
782 }
783
784 #define get_htmldoc5_iface(u) _get_htmldoc5_iface(__LINE__,u)
785 static IHTMLDocument5 *_get_htmldoc5_iface(unsigned line, IUnknown *unk)
786 {
787     IHTMLDocument5 *doc;
788     HRESULT hres;
789
790     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument5, (void**)&doc);
791     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument5: %08x\n", hres);
792     return doc;
793 }
794
795 #define get_img_iface(u) _get_img_iface(__LINE__,u)
796 static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk)
797 {
798     IHTMLImgElement *img;
799     HRESULT hres;
800
801     hres = IUnknown_QueryInterface(unk, &IID_IHTMLImgElement, (void**)&img);
802     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLImgElement: %08x\n", hres);
803     return img;
804 }
805
806 #define get_anchor_iface(u) _get_anchor_iface(__LINE__,u)
807 static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
808 {
809     IHTMLAnchorElement *anchor;
810     HRESULT hres;
811
812     hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor);
813     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres);
814     return anchor;
815 }
816
817 #define get_textarea_iface(u) _get_textarea_iface(__LINE__,u)
818 static IHTMLTextAreaElement *_get_textarea_iface(unsigned line, IUnknown *unk)
819 {
820     IHTMLTextAreaElement *textarea;
821     HRESULT hres;
822
823     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextAreaElement, (void**)&textarea);
824     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextAreaElement: %08x\n", hres);
825     return textarea;
826 }
827
828 #define get_select_iface(u) _get_select_iface(__LINE__,u)
829 static IHTMLSelectElement *_get_select_iface(unsigned line, IUnknown *unk)
830 {
831     IHTMLSelectElement *select;
832     HRESULT hres;
833
834     hres = IUnknown_QueryInterface(unk, &IID_IHTMLSelectElement, (void**)&select);
835     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLSelectElement: %08x\n", hres);
836     return select;
837 }
838
839 #define get_form_iface(u) _get_form_iface(__LINE__,u)
840 static IHTMLFormElement *_get_form_iface(unsigned line, IUnknown *unk)
841 {
842     IHTMLFormElement *form;
843     HRESULT hres;
844
845     hres = IUnknown_QueryInterface(unk, &IID_IHTMLFormElement, (void**)&form);
846     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLFormElement: %08x\n", hres);
847     return form;
848 }
849
850 #define get_text_iface(u) _get_text_iface(__LINE__,u)
851 static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk)
852 {
853     IHTMLDOMTextNode *text;
854     HRESULT hres;
855
856     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text);
857     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres);
858     return text;
859 }
860
861 #define get_comment_iface(u) _get_comment_iface(__LINE__,u)
862 static IHTMLCommentElement *_get_comment_iface(unsigned line, IUnknown *unk)
863 {
864     IHTMLCommentElement *comment;
865     HRESULT hres;
866
867     hres = IUnknown_QueryInterface(unk, &IID_IHTMLCommentElement, (void**)&comment);
868     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLCommentElement: %08x\n", hres);
869     return comment;
870 }
871
872 #define get_object_iface(u) _get_object_iface(__LINE__,u)
873 static IHTMLObjectElement *_get_object_iface(unsigned line, IUnknown *unk)
874 {
875     IHTMLObjectElement *obj;
876     HRESULT hres;
877
878     hres = IUnknown_QueryInterface(unk, &IID_IHTMLObjectElement, (void**)&obj);
879     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLObjectElement: %08x\n", hres);
880     return obj;
881 }
882
883 #define get_style_iface(u) _get_style_iface(__LINE__,u)
884 static IHTMLStyleElement *_get_style_iface(unsigned line, IUnknown *unk)
885 {
886     IHTMLStyleElement *obj;
887     HRESULT hres;
888
889     hres = IUnknown_QueryInterface(unk, &IID_IHTMLStyleElement, (void**)&obj);
890     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLStyleElement: %08x\n", hres);
891     return obj;
892 }
893
894 #define get_metaelem_iface(u) _get_metaelem_iface(__LINE__,u)
895 static IHTMLMetaElement *_get_metaelem_iface(unsigned line, IUnknown *unk)
896 {
897     IHTMLMetaElement *ret;
898     HRESULT hres;
899
900     hres = IUnknown_QueryInterface(unk, &IID_IHTMLMetaElement, (void**)&ret);
901     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLMetaElement: %08x\n", hres);
902     return ret;
903 }
904
905 #define get_link_iface(u) _get_link_iface(__LINE__,u)
906 static IHTMLLinkElement *_get_link_iface(unsigned line, IUnknown *unk)
907 {
908     IHTMLLinkElement *ret;
909     HRESULT hres;
910
911     hres = IUnknown_QueryInterface(unk, &IID_IHTMLLinkElement, (void**)&ret);
912     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLinkElement: %08x\n", hres);
913     return ret;
914 }
915
916 #define get_iframe2_iface(u) _get_iframe2_iface(__LINE__,u)
917 static IHTMLIFrameElement2 *_get_iframe2_iface(unsigned line, IUnknown *unk)
918 {
919     IHTMLIFrameElement2 *ret;
920     HRESULT hres;
921
922     hres = IUnknown_QueryInterface(unk, &IID_IHTMLIFrameElement2, (void**)&ret);
923     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLIFrameElement: %08x\n", hres);
924     return ret;
925 }
926
927 #define get_button_iface(u) _get_button_iface(__LINE__,u)
928 static IHTMLButtonElement *_get_button_iface(unsigned line, IUnknown *unk)
929 {
930     IHTMLButtonElement *ret;
931     HRESULT hres;
932
933     hres = IUnknown_QueryInterface(unk, &IID_IHTMLButtonElement, (void**)&ret);
934     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLButtonElement: %08x\n", hres);
935     return ret;
936 }
937
938 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
939 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
940 {
941     IHTMLDOMNode *node = _get_node_iface(line, unk);
942     BSTR name;
943     HRESULT hres;
944
945     hres = IHTMLDOMNode_get_nodeName(node, &name);
946     IHTMLDOMNode_Release(node);
947     ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres);
948     ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname);
949
950     SysFreeString(name);
951 }
952
953 #define get_owner_doc(u) _get_owner_doc(__LINE__,u)
954 static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
955 {
956     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
957     IDispatch *disp = (void*)0xdeadbeef;
958     IHTMLDocument2 *doc = NULL;
959     HRESULT hres;
960
961     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
962     IHTMLDOMNode2_Release(node);
963     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
964
965     if(disp) {
966         hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
967         IDispatch_Release(disp);
968         ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
969     }
970
971     return doc;
972 }
973
974 #define get_doc_window(d) _get_doc_window(__LINE__,d)
975 static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
976 {
977     IHTMLWindow2 *window;
978     HRESULT hres;
979
980     window = NULL;
981     hres = IHTMLDocument2_get_parentWindow(doc, &window);
982     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
983     ok_(__FILE__,line)(window != NULL, "window == NULL\n");
984
985     return window;
986 }
987
988 #define clone_node(n,d) _clone_node(__LINE__,n,d)
989 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
990 {
991     IHTMLDOMNode *node = _get_node_iface(line, unk);
992     IHTMLDOMNode *ret = NULL;
993     HRESULT hres;
994
995     hres = IHTMLDOMNode_cloneNode(node, deep, &ret);
996     IHTMLDOMNode_Release(node);
997     ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres);
998     ok_(__FILE__,line)(ret != NULL, "ret == NULL\n");
999
1000     return ret;
1001
1002 }
1003
1004 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
1005 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
1006 {
1007     IHTMLElement *elem = _get_elem_iface(line, unk);
1008     BSTR tag;
1009     HRESULT hres;
1010
1011     hres = IHTMLElement_get_tagName(elem, &tag);
1012     IHTMLElement_Release(elem);
1013     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
1014     ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
1015
1016     SysFreeString(tag);
1017 }
1018
1019 #define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t)
1020 static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type)
1021 {
1022     _test_elem_tag(line, unk, elem_type_infos[type].tag);
1023     _test_ifaces(line, unk, elem_type_infos[type].iids);
1024
1025     if(elem_type_infos[type].dispiid && type != ET_A)
1026         _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]");
1027 }
1028
1029 #define get_node_type(n) _get_node_type(__LINE__,n)
1030 static LONG _get_node_type(unsigned line, IUnknown *unk)
1031 {
1032     IHTMLDOMNode *node = _get_node_iface(line, unk);
1033     LONG type = -1;
1034     HRESULT hres;
1035
1036     hres = IHTMLDOMNode_get_nodeType(node, &type);
1037     ok(hres == S_OK, "get_nodeType failed: %08x\n", hres);
1038
1039     IHTMLDOMNode_Release(node);
1040
1041     return type;
1042 }
1043
1044 #define get_child_nodes(u) _get_child_nodes(__LINE__,u)
1045 static IHTMLDOMChildrenCollection *_get_child_nodes(unsigned line, IUnknown *unk)
1046 {
1047     IHTMLDOMNode *node = _get_node_iface(line, unk);
1048     IHTMLDOMChildrenCollection *col = NULL;
1049     IDispatch *disp;
1050     HRESULT hres;
1051
1052     hres = IHTMLDOMNode_get_childNodes(node, &disp);
1053     IHTMLDOMNode_Release(node);
1054     ok_(__FILE__,line) (hres == S_OK, "get_childNodes failed: %08x\n", hres);
1055     if(FAILED(hres))
1056         return NULL;
1057
1058     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMChildrenCollection, (void**)&col);
1059     IDispatch_Release(disp);
1060     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMChildrenCollection: %08x\n", hres);
1061
1062     return col;
1063 }
1064
1065 #define get_child_item(c,i) _get_child_item(__LINE__,c,i)
1066 static IHTMLDOMNode *_get_child_item(unsigned line, IHTMLDOMChildrenCollection *col, LONG idx)
1067 {
1068     IHTMLDOMNode *node = NULL;
1069     IDispatch *disp;
1070     HRESULT hres;
1071
1072     hres = IHTMLDOMChildrenCollection_item(col, idx, &disp);
1073     ok(hres == S_OK, "item failed: %08x\n", hres);
1074
1075     node = _get_node_iface(line, (IUnknown*)disp);
1076     IDispatch_Release(disp);
1077
1078     return node;
1079 }
1080
1081 #define test_elem_attr(e,n,v) _test_elem_attr(__LINE__,e,n,v)
1082 static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, const char *exval)
1083 {
1084     VARIANT value;
1085     BSTR tmp;
1086     HRESULT hres;
1087
1088     VariantInit(&value);
1089
1090     tmp = a2bstr(name);
1091     hres = IHTMLElement_getAttribute(elem, tmp, 0, &value);
1092     SysFreeString(tmp);
1093     ok_(__FILE__,line) (hres == S_OK, "getAttribute failed: %08x\n", hres);
1094
1095     if(exval) {
1096         ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value));
1097         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value)));
1098     }else {
1099         ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value));
1100     }
1101
1102     VariantClear(&value);
1103 }
1104
1105 #define test_elem_offset(a,b) _test_elem_offset(__LINE__,a,b)
1106 static void _test_elem_offset(unsigned line, IUnknown *unk, const char *parent_tag)
1107 {
1108     IHTMLElement *elem = _get_elem_iface(line, unk);
1109     IHTMLElement *off_parent;
1110     LONG l;
1111     HRESULT hres;
1112
1113     hres = IHTMLElement_get_offsetTop(elem, &l);
1114     ok_(__FILE__,line) (hres == S_OK, "get_offsetTop failed: %08x\n", hres);
1115
1116     hres = IHTMLElement_get_offsetHeight(elem, &l);
1117     ok_(__FILE__,line) (hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
1118
1119     hres = IHTMLElement_get_offsetWidth(elem, &l);
1120     ok_(__FILE__,line) (hres == S_OK, "get_offsetWidth failed: %08x\n", hres);
1121
1122     hres = IHTMLElement_get_offsetLeft(elem, &l);
1123     ok_(__FILE__,line) (hres == S_OK, "get_offsetLeft failed: %08x\n", hres);
1124
1125     hres = IHTMLElement_get_offsetParent(elem, &off_parent);
1126     ok_(__FILE__,line) (hres == S_OK, "get_offsetParent failed: %08x\n", hres);
1127
1128     _test_elem_tag(line, (IUnknown*)off_parent, parent_tag);
1129     IHTMLElement_Release(off_parent);
1130
1131     IHTMLElement_Release(elem);
1132 }
1133
1134 #define get_doc_node(d) _get_doc_node(__LINE__,d)
1135 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
1136 {
1137     IHTMLWindow2 *window;
1138     IHTMLDocument2 *ret;
1139     HRESULT hres;
1140
1141     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1142     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1143
1144     hres = IHTMLWindow2_get_document(window, &ret);
1145     ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres);
1146     ok_(__FILE__,line)(ret != NULL, "document = NULL\n");
1147
1148     return ret;
1149 }
1150
1151 #define test_window_name(d,e) _test_window_name(__LINE__,d,e)
1152 static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
1153 {
1154     BSTR name;
1155     HRESULT hres;
1156
1157     hres = IHTMLWindow2_get_name(window, &name);
1158     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1159     if(exname)
1160         ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
1161     else
1162         ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
1163     SysFreeString(name);
1164 }
1165
1166 #define set_window_name(w,n) _set_window_name(__LINE__,w,n)
1167 static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
1168 {
1169     BSTR str;
1170     HRESULT hres;
1171
1172     str = a2bstr(name);
1173     hres = IHTMLWindow2_put_name(window, str);
1174     SysFreeString(str);
1175     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1176
1177     _test_window_name(line, window, name);
1178 }
1179
1180 #define test_window_status(d) _test_window_status(__LINE__,d)
1181 static void _test_window_status(unsigned line, IHTMLWindow2 *window)
1182 {
1183     BSTR status;
1184     HRESULT hres;
1185
1186     status = (void*)0xdeadbeef;
1187     hres = IHTMLWindow2_get_status(window, &status);
1188     ok_(__FILE__,line)(hres == S_OK, "get_status failed: %08x\n", hres);
1189     ok_(__FILE__,line)(!status, "status = %s\n", wine_dbgstr_w(status));
1190     SysFreeString(status);
1191 }
1192
1193 #define set_window_status(w,n) _set_window_status(__LINE__,w,n)
1194 static void _set_window_status(unsigned line, IHTMLWindow2 *window, const char *status)
1195 {
1196     BSTR str;
1197     HRESULT hres;
1198
1199     str = a2bstr(status);
1200     hres = IHTMLWindow2_put_status(window, str);
1201     SysFreeString(str);
1202     ok_(__FILE__,line)(hres == S_OK, "put_status failed: %08x\n", hres);
1203 }
1204
1205 #define test_window_length(w,l) _test_window_length(__LINE__,w,l)
1206 static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
1207 {
1208     LONG length = -1;
1209     HRESULT hres;
1210
1211     hres = IHTMLWindow2_get_length(window, &length);
1212     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
1213     ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
1214 }
1215
1216 #define get_frame_content_window(e) _get_frame_content_window(__LINE__,e)
1217 static IHTMLWindow2 *_get_frame_content_window(unsigned line, IUnknown *elem)
1218 {
1219     IHTMLFrameBase2 *base2;
1220     IHTMLWindow2 *window;
1221     HRESULT hres;
1222
1223     hres = IUnknown_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
1224     ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
1225
1226     window = NULL;
1227     hres = IHTMLFrameBase2_get_contentWindow(base2, &window);
1228     IHTMLFrameBase2_Release(base2);
1229     ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
1230     ok(window != NULL, "contentWindow = NULL\n");
1231
1232     return window;
1233 }
1234
1235 static void test_get_set_attr(IHTMLDocument2 *doc)
1236 {
1237     IHTMLElement *elem;
1238     IHTMLDocument3 *doc3;
1239     HRESULT hres;
1240     BSTR bstr;
1241     VARIANT val;
1242
1243     /* grab an element to test with */
1244     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1245     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
1246
1247     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1248     IHTMLDocument3_Release(doc3);
1249     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
1250
1251     /* get a non-present attribute */
1252     bstr = a2bstr("notAnAttribute");
1253     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1254     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1255     ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val));
1256     VariantClear(&val);
1257     SysFreeString(bstr);
1258
1259     /* get a present attribute */
1260     bstr = a2bstr("scrollHeight");
1261     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1262     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1263     ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val));
1264     VariantClear(&val);
1265     SysFreeString(bstr);
1266
1267     /* create a new BSTR attribute */
1268     bstr = a2bstr("newAttribute");
1269
1270     V_VT(&val) = VT_BSTR;
1271     V_BSTR(&val) = a2bstr("the value");
1272     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1273     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1274     VariantClear(&val);
1275
1276     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1277     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1278     ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val));
1279     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)));
1280     VariantClear(&val);
1281
1282     /* overwrite the attribute with a BOOL */
1283     V_VT(&val) = VT_BOOL;
1284     V_BOOL(&val) = VARIANT_TRUE;
1285     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1286     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1287     VariantClear(&val);
1288
1289     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1290     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1291     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1292     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1293     VariantClear(&val);
1294
1295     SysFreeString(bstr);
1296
1297     /* case-insensitive */
1298     bstr = a2bstr("newattribute");
1299     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1300     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1301     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1302     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1303     VariantClear(&val);
1304     SysFreeString(bstr);
1305
1306     IHTMLElement_Release(elem);
1307 }
1308
1309 #define get_doc_elem(d) _get_doc_elem(__LINE__,d)
1310 static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc)
1311 {
1312     IHTMLElement *elem;
1313     IHTMLDocument3 *doc3;
1314     HRESULT hres;
1315
1316     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1317     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
1318     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1319     ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres);
1320     IHTMLDocument3_Release(doc3);
1321
1322     return elem;
1323 }
1324
1325 #define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h)
1326 static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref)
1327 {
1328     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1329     BSTR str;
1330     HRESULT hres;
1331
1332     hres = IHTMLAnchorElement_get_href(anchor, &str);
1333     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1334     ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref);
1335     SysFreeString(str);
1336
1337     _test_disp_value(line, unk, exhref);
1338 }
1339
1340 #define test_anchor_put_href(a,h) _test_anchor_put_href(__LINE__,a,h)
1341 static void _test_anchor_put_href(unsigned line, IUnknown *unk, const char *exhref)
1342 {
1343     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1344     BSTR str;
1345     HRESULT hres;
1346
1347     str = a2bstr(exhref);
1348     hres = IHTMLAnchorElement_put_href(anchor, str);
1349     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1350     SysFreeString(str);
1351
1352     _test_disp_value(line, unk, exhref);
1353 }
1354
1355 #define test_anchor_get_target(a,h) _test_anchor_get_target(__LINE__,a,h)
1356 static void _test_anchor_get_target(unsigned line, IUnknown *unk, const char *target)
1357 {
1358     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1359     BSTR str;
1360     HRESULT hres;
1361
1362     hres = IHTMLAnchorElement_get_target(anchor, &str);
1363     ok_(__FILE__,line)(hres == S_OK, "get_target failed: %08x\n", hres);
1364     if(target)
1365         ok_(__FILE__,line)(!strcmp_wa(str, target), "target = %s, expected %s\n", wine_dbgstr_w(str), target);
1366     else
1367         ok_(__FILE__,line)(str == NULL, "target = %s, expected NULL\n", wine_dbgstr_w(str));
1368     SysFreeString(str);
1369 }
1370
1371 #define test_anchor_put_target(a,h) _test_anchor_put_target(__LINE__,a,h)
1372 static void _test_anchor_put_target(unsigned line, IUnknown *unk, const char *target)
1373 {
1374     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1375     BSTR str;
1376     HRESULT hres;
1377
1378     str = target ? a2bstr(target) : NULL;
1379     hres = IHTMLAnchorElement_put_target(anchor, str);
1380     ok_(__FILE__,line)(hres == S_OK, "put_target failed: %08x\n", hres);
1381     SysFreeString(str);
1382 }
1383
1384 #define test_anchor_name(a,h) _test_anchor_name(__LINE__,a,h)
1385 static void _test_anchor_name(unsigned line, IUnknown *unk, const char *name)
1386 {
1387     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1388     BSTR str;
1389     HRESULT hres;
1390
1391     hres = IHTMLAnchorElement_get_name(anchor, &str);
1392     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1393     if(name)
1394         ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
1395     else
1396         ok_(__FILE__,line)(str == NULL, "name = %s, expected NULL\n", wine_dbgstr_w(str));
1397     SysFreeString(str);
1398 }
1399
1400 #define test_anchor_put_name(a,h) _test_anchor_put_name(__LINE__,a,h)
1401 static void _test_anchor_put_name(unsigned line, IUnknown *unk, const char *name)
1402 {
1403     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1404     BSTR str;
1405     HRESULT hres;
1406
1407     str = name ? a2bstr(name) : NULL;
1408     hres = IHTMLAnchorElement_put_name(anchor, str);
1409     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1410     SysFreeString(str);
1411
1412     _test_anchor_name(line, unk, name);
1413 }
1414
1415 #define test_anchor_hostname(a,h) _test_anchor_hostname(__LINE__,a,h)
1416 static void _test_anchor_hostname(unsigned line, IUnknown *unk, const char *hostname)
1417 {
1418     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1419     BSTR str;
1420     HRESULT hres;
1421
1422     hres = IHTMLAnchorElement_get_hostname(anchor, &str);
1423     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1424     if(hostname)
1425         ok_(__FILE__,line)(!strcmp_wa(str, hostname), "hostname = %s, expected %s\n", wine_dbgstr_w(str), hostname);
1426     else
1427         ok_(__FILE__,line)(str == NULL, "hostname = %s, expected NULL\n", wine_dbgstr_w(str));
1428     SysFreeString(str);
1429 }
1430
1431 #define test_option_text(o,t) _test_option_text(__LINE__,o,t)
1432 static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text)
1433 {
1434     BSTR bstr;
1435     HRESULT hres;
1436
1437     hres = IHTMLOptionElement_get_text(option, &bstr);
1438     ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres);
1439     ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr));
1440     SysFreeString(bstr);
1441 }
1442
1443 #define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t)
1444 static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text)
1445 {
1446     BSTR bstr;
1447     HRESULT hres;
1448
1449     bstr = a2bstr(text);
1450     hres = IHTMLOptionElement_put_text(option, bstr);
1451     SysFreeString(bstr);
1452     ok(hres == S_OK, "put_text failed: %08x\n", hres);
1453
1454     _test_option_text(line, option, text);
1455 }
1456
1457 #define test_option_value(o,t) _test_option_value(__LINE__,o,t)
1458 static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value)
1459 {
1460     BSTR bstr;
1461     HRESULT hres;
1462
1463     hres = IHTMLOptionElement_get_value(option, &bstr);
1464     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1465     ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr));
1466     SysFreeString(bstr);
1467 }
1468
1469 #define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t)
1470 static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value)
1471 {
1472     BSTR bstr;
1473     HRESULT hres;
1474
1475     bstr = a2bstr(value);
1476     hres = IHTMLOptionElement_put_value(option, bstr);
1477     SysFreeString(bstr);
1478     ok(hres == S_OK, "put_value failed: %08x\n", hres);
1479
1480     _test_option_value(line, option, value);
1481 }
1482
1483 #define test_option_selected(o,s) _test_option_selected(__LINE__,o,s)
1484 static void _test_option_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex)
1485 {
1486     VARIANT_BOOL b = 0x100;
1487     HRESULT hres;
1488
1489     hres = IHTMLOptionElement_get_selected(option, &b);
1490     ok_(__FILE__,line)(hres == S_OK, "get_selected failed: %08x\n", hres);
1491     ok_(__FILE__,line)(b == ex, "selected = %x, expected %x\n", b, ex);
1492 }
1493
1494 #define test_option_put_selected(o,s) _test_option_put_selected(__LINE__,o,s)
1495 static void _test_option_put_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b)
1496 {
1497     HRESULT hres;
1498
1499     hres = IHTMLOptionElement_put_selected(option, b);
1500     ok_(__FILE__,line)(hres == S_OK, "put_selected failed: %08x\n", hres);
1501     _test_option_selected(line, option, b);
1502 }
1503
1504 #define test_textarea_value(t,v) _test_textarea_value(__LINE__,t,v)
1505 static void _test_textarea_value(unsigned line, IUnknown *unk, const char *exval)
1506 {
1507     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1508     BSTR value = (void*)0xdeadbeef;
1509     HRESULT hres;
1510
1511     hres = IHTMLTextAreaElement_get_value(textarea, &value);
1512     IHTMLTextAreaElement_Release(textarea);
1513     ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres);
1514     if(exval)
1515         ok_(__FILE__,line)(!strcmp_wa(value, exval), "value = %s, expected %s\n", wine_dbgstr_w(value), exval);
1516     else
1517         ok_(__FILE__,line)(!value, "value = %p\n", value);
1518     SysFreeString(value);
1519 }
1520
1521 #define test_textarea_put_value(t,v) _test_textarea_put_value(__LINE__,t,v)
1522 static void _test_textarea_put_value(unsigned line, IUnknown *unk, const char *value)
1523 {
1524     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1525     BSTR tmp = a2bstr(value);
1526     HRESULT hres;
1527
1528     hres = IHTMLTextAreaElement_put_value(textarea, tmp);
1529     IHTMLTextAreaElement_Release(textarea);
1530     ok_(__FILE__,line)(hres == S_OK, "put_value failed: %08x\n", hres);
1531     SysFreeString(tmp);
1532
1533     _test_textarea_value(line, unk, value);
1534 }
1535
1536 #define test_textarea_readonly(t,v) _test_textarea_readonly(__LINE__,t,v)
1537 static void _test_textarea_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL ex)
1538 {
1539     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1540     VARIANT_BOOL b = 0x100;
1541     HRESULT hres;
1542
1543     hres = IHTMLTextAreaElement_get_readOnly(textarea, &b);
1544     IHTMLTextAreaElement_Release(textarea);
1545     ok_(__FILE__,line)(hres == S_OK, "get_readOnly failed: %08x\n", hres);
1546     ok_(__FILE__,line)(b == ex, "readOnly = %x, expected %x\n", b, ex);
1547 }
1548
1549 #define test_textarea_put_readonly(t,v) _test_textarea_put_readonly(__LINE__,t,v)
1550 static void _test_textarea_put_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL b)
1551 {
1552     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1553     HRESULT hres;
1554
1555     hres = IHTMLTextAreaElement_put_readOnly(textarea, b);
1556     IHTMLTextAreaElement_Release(textarea);
1557     ok_(__FILE__,line)(hres == S_OK, "put_readOnly failed: %08x\n", hres);
1558
1559     _test_textarea_readonly(line, unk, b);
1560 }
1561
1562 #define test_textarea_type(t) _test_textarea_type(__LINE__,t)
1563 static void _test_textarea_type(unsigned line, IUnknown *unk)
1564 {
1565     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1566     BSTR type = (void*)0xdeadbeef;
1567     HRESULT hres;
1568
1569     hres = IHTMLTextAreaElement_get_type(textarea, &type);
1570     IHTMLTextAreaElement_Release(textarea);
1571     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
1572     ok_(__FILE__,line)(!strcmp_wa(type, "textarea"), "type = %s, expected textarea\n", wine_dbgstr_w(type));
1573     SysFreeString(type);
1574 }
1575
1576 #define test_comment_text(c,t) _test_comment_text(__LINE__,c,t)
1577 static void _test_comment_text(unsigned line, IUnknown *unk, const char *extext)
1578 {
1579     IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1580     BSTR text;
1581     HRESULT hres;
1582
1583     text = a2bstr(extext);
1584     hres = IHTMLCommentElement_get_text(comment, &text);
1585     ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
1586     ok_(__FILE__,line)(!strcmp_wa(text, extext), "text = \"%s\", expected \"%s\"\n", wine_dbgstr_w(text), extext);
1587
1588     IHTMLCommentElement_Release(comment);
1589     SysFreeString(text);
1590 }
1591
1592 #define test_comment_attrs(c) _test_comment_attrs(__LINE__,c)
1593 static void _test_comment_attrs(unsigned line, IUnknown *unk)
1594 {
1595     IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1596     IHTMLElement *elem = _get_elem_iface(__LINE__,unk);
1597     IHTMLElement4 *elem4 = _get_elem4_iface(__LINE__,unk);
1598     IHTMLDOMAttribute *attr;
1599     BSTR name = a2bstr("test");
1600     VARIANT val;
1601     HRESULT hres;
1602
1603     hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1604     ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1605     ok(attr == NULL, "attr != NULL\n");
1606
1607     V_VT(&val) = VT_I4;
1608     V_I4(&val) = 1234;
1609     hres = IHTMLElement_setAttribute(elem, name, val, 0);
1610     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1611
1612     hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1613     ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1614     ok(attr != NULL, "attr == NULL\n");
1615
1616     IHTMLDOMAttribute_Release(attr);
1617     IHTMLCommentElement_Release(comment);
1618     IHTMLElement_Release(elem);
1619     IHTMLElement4_Release(elem4);
1620     SysFreeString(name);
1621 }
1622
1623 #define test_object_vspace(u,s) _test_object_vspace(__LINE__,u,s)
1624 static void _test_object_vspace(unsigned line, IUnknown *unk, LONG exl)
1625 {
1626     IHTMLObjectElement *object = _get_object_iface(line, unk);
1627     LONG l;
1628     HRESULT hres;
1629
1630     l = 0xdeadbeef;
1631     hres = IHTMLObjectElement_get_vspace(object, &l);
1632     ok_(__FILE__,line)(hres == S_OK, "get_vspace failed: %08x\n", hres);
1633     ok_(__FILE__,line)(l == exl, "vspace=%d, expected %d\n", l, exl);
1634     IHTMLObjectElement_Release(object);
1635 }
1636
1637 #define test_object_name(a,b) _test_object_name(__LINE__,a,b)
1638 static void _test_object_name(unsigned line, IHTMLElement *elem, const char *exname)
1639 {
1640     IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1641     BSTR str;
1642     HRESULT hres;
1643
1644     str = (void*)0xdeadbeef;
1645     hres = IHTMLObjectElement_get_name(object, &str);
1646     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1647     if(exname)
1648         ok_(__FILE__,line)(!strcmp_wa(str, exname), "name=%s, expected %s\n", wine_dbgstr_w(str), exname);
1649     else
1650         ok_(__FILE__,line)(!str, "name=%s, expected NULL\n", wine_dbgstr_w(str));
1651     SysFreeString(str);
1652     IHTMLObjectElement_Release(object);
1653 }
1654
1655 #define set_object_name(a,b) _set_object_name(__LINE__,a,b)
1656 static void _set_object_name(unsigned line, IHTMLElement *elem, const char *name)
1657 {
1658     IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1659     BSTR str;
1660     HRESULT hres;
1661
1662     str = a2bstr(name);
1663     hres = IHTMLObjectElement_put_name(object, str);
1664     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1665     SysFreeString(str);
1666     IHTMLObjectElement_Release(object);
1667
1668     _test_object_name(line, elem, name);
1669 }
1670
1671 #define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v)
1672 static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc,
1673         const char *txt, const char *val)
1674 {
1675     IHTMLOptionElementFactory *factory;
1676     IHTMLOptionElement *option;
1677     IHTMLWindow2 *window;
1678     VARIANT text, value, empty;
1679     HRESULT hres;
1680
1681     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1682     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1683
1684     hres = IHTMLWindow2_get_Option(window, &factory);
1685     IHTMLWindow2_Release(window);
1686     ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres);
1687
1688     V_VT(&text) = VT_BSTR;
1689     V_BSTR(&text) = a2bstr(txt);
1690     V_VT(&value) = VT_BSTR;
1691     V_BSTR(&value) = a2bstr(val);
1692     V_VT(&empty) = VT_EMPTY;
1693
1694     hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option);
1695     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1696
1697     IHTMLOptionElementFactory_Release(factory);
1698     VariantClear(&text);
1699     VariantClear(&value);
1700
1701     _test_option_text(line, option, txt);
1702     _test_option_value(line, option, val);
1703     _test_option_selected(line, option, VARIANT_FALSE);
1704
1705     return option;
1706 }
1707
1708 #define test_img_width(o,w) _test_img_width(__LINE__,o,w)
1709 static void _test_img_width(unsigned line, IHTMLImgElement *img, const LONG exp)
1710 {
1711     LONG found = -1;
1712     HRESULT hres;
1713
1714     hres = IHTMLImgElement_get_width(img, &found);
1715     ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
1716     ok_(__FILE__,line) (found == exp, "width=%d\n", found);
1717 }
1718
1719 #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
1720 static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const LONG width)
1721 {
1722     HRESULT hres;
1723
1724     hres = IHTMLImgElement_put_width(img, width);
1725     ok(hres == S_OK, "put_width failed: %08x\n", hres);
1726
1727     _test_img_width(line, img, width);
1728 }
1729
1730 #define test_img_height(o,h) _test_img_height(__LINE__,o,h)
1731 static void _test_img_height(unsigned line, IHTMLImgElement *img, const LONG exp)
1732 {
1733     LONG found = -1;
1734     HRESULT hres;
1735
1736     hres = IHTMLImgElement_get_height(img, &found);
1737     ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
1738     ok_(__FILE__,line) (found == exp, "height=%d\n", found);
1739 }
1740
1741 #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
1742 static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const LONG height)
1743 {
1744     HRESULT hres;
1745
1746     hres = IHTMLImgElement_put_height(img, height);
1747     ok(hres == S_OK, "put_height failed: %08x\n", hres);
1748
1749     _test_img_height(line, img, height);
1750 }
1751
1752 #define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
1753 static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
1754         LONG wdth, LONG hght)
1755 {
1756     IHTMLImageElementFactory *factory;
1757     IHTMLImgElement *img;
1758     IHTMLWindow2 *window;
1759     VARIANT width, height;
1760     char buf[16];
1761     HRESULT hres;
1762
1763     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1764     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1765
1766     hres = IHTMLWindow2_get_Image(window, &factory);
1767     IHTMLWindow2_Release(window);
1768     ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
1769
1770     test_ifaces((IUnknown*)factory, img_factory_iids);
1771     test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
1772
1773     if(wdth >= 0){
1774         snprintf(buf, 16, "%d", wdth);
1775         V_VT(&width) = VT_BSTR;
1776         V_BSTR(&width) = a2bstr(buf);
1777     }else{
1778         V_VT(&width) = VT_EMPTY;
1779         wdth = 0;
1780     }
1781
1782     if(hght >= 0){
1783         snprintf(buf, 16, "%d", hght);
1784         V_VT(&height) = VT_BSTR;
1785         V_BSTR(&height) = a2bstr(buf);
1786     }else{
1787         V_VT(&height) = VT_EMPTY;
1788         hght = 0;
1789     }
1790
1791     hres = IHTMLImageElementFactory_create(factory, width, height, &img);
1792     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1793
1794     IHTMLImageElementFactory_Release(factory);
1795     VariantClear(&width);
1796     VariantClear(&height);
1797
1798     if(SUCCEEDED(hres)) {
1799         _test_img_width(line, img, wdth);
1800         _test_img_height(line, img, hght);
1801         return img;
1802     }
1803
1804     return NULL;
1805 }
1806
1807 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
1808 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
1809 {
1810     LONG len = 0xdeadbeef;
1811     HRESULT hres;
1812
1813     hres = IHTMLSelectElement_get_length(select, &len);
1814     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1815     ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length);
1816 }
1817
1818 #define test_select_put_length(s,l) _test_select_put_length(__LINE__,s,l)
1819 static void _test_select_put_length(unsigned line, IUnknown *unk, LONG length)
1820 {
1821     IHTMLSelectElement *select = _get_select_iface(line, unk);
1822     HRESULT hres;
1823
1824     hres = IHTMLSelectElement_put_length(select, length);
1825     ok_(__FILE__,line) (hres == S_OK, "put_length failed: %08x\n", hres);
1826     _test_select_length(line, select, length);
1827     IHTMLSelectElement_Release(select);
1828 }
1829
1830 #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i)
1831 static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1832 {
1833     LONG idx = 0xdeadbeef;
1834     HRESULT hres;
1835
1836     hres = IHTMLSelectElement_get_selectedIndex(select, &idx);
1837     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1838     ok_(__FILE__,line) (idx == index, "idx=%d, expected %d\n", idx, index);
1839 }
1840
1841 #define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i)
1842 static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1843 {
1844     HRESULT hres;
1845
1846     hres = IHTMLSelectElement_put_selectedIndex(select, index);
1847     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1848     _test_select_selidx(line, select, index);
1849 }
1850
1851 #define test_select_value(s,v) _test_select_value(__LINE__,s,v)
1852 static void _test_select_value(unsigned line, IHTMLSelectElement *select, const char *exval)
1853 {
1854     BSTR val;
1855     HRESULT hres;
1856
1857     hres = IHTMLSelectElement_get_value(select, &val);
1858     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1859     if(exval)
1860         ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val));
1861     else
1862         ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val));
1863     SysFreeString(val);
1864 }
1865
1866 #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v)
1867 static void _test_select_set_value(unsigned line, IHTMLSelectElement *select, const char *val)
1868 {
1869     BSTR bstr;
1870     HRESULT hres;
1871
1872     bstr = a2bstr(val);
1873     hres = IHTMLSelectElement_put_value(select, bstr);
1874     SysFreeString(bstr);
1875     ok_(__FILE__,line) (hres == S_OK, "put_value failed: %08x\n", hres);
1876 }
1877
1878 #define test_select_type(s,t) _test_select_type(__LINE__,s,t)
1879 static void _test_select_type(unsigned line, IHTMLSelectElement *select, const char *extype)
1880 {
1881     BSTR type;
1882     HRESULT hres;
1883
1884     hres = IHTMLSelectElement_get_type(select, &type);
1885     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
1886     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
1887     SysFreeString(type);
1888 }
1889
1890 #define test_range_text(r,t) _test_range_text(__LINE__,r,t)
1891 static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext)
1892 {
1893     BSTR text;
1894     HRESULT hres;
1895
1896     hres = IHTMLTxtRange_get_text(range, &text);
1897     ok_(__FILE__, line) (hres == S_OK, "get_text failed: %08x\n", hres);
1898
1899     if(extext) {
1900         ok_(__FILE__, line) (text != NULL, "text == NULL\n");
1901         ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext);
1902     }else {
1903         ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text));
1904     }
1905
1906     SysFreeString(text);
1907
1908 }
1909
1910 #define test_range_collapse(r,b) _test_range_collapse(__LINE__,r,b)
1911 static void _test_range_collapse(unsigned line, IHTMLTxtRange *range, BOOL b)
1912 {
1913     HRESULT hres;
1914
1915     hres = IHTMLTxtRange_collapse(range, b);
1916     ok_(__FILE__, line) (hres == S_OK, "collapse failed: %08x\n", hres);
1917     _test_range_text(line, range, NULL);
1918 }
1919
1920 #define test_range_expand(r,u,b,t) _test_range_expand(__LINE__,r,u,b,t)
1921 static void _test_range_expand(unsigned line, IHTMLTxtRange *range, LPWSTR unit,
1922         VARIANT_BOOL exb, const char *extext)
1923 {
1924     VARIANT_BOOL b = 0xe0e0;
1925     HRESULT hres;
1926
1927     hres = IHTMLTxtRange_expand(range, unit, &b);
1928     ok_(__FILE__,line) (hres == S_OK, "expand failed: %08x\n", hres);
1929     ok_(__FILE__,line) (b == exb, "b=%x, expected %x\n", b, exb);
1930     _test_range_text(line, range, extext);
1931 }
1932
1933 #define test_range_move(r,u,c,e) _test_range_move(__LINE__,r,u,c,e)
1934 static void _test_range_move(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1935 {
1936     LONG c = 0xdeadbeef;
1937     HRESULT hres;
1938
1939     hres = IHTMLTxtRange_move(range, unit, cnt, &c);
1940     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1941     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1942     _test_range_text(line, range, NULL);
1943 }
1944
1945 #define test_range_movestart(r,u,c,e) _test_range_movestart(__LINE__,r,u,c,e)
1946 static void _test_range_movestart(unsigned line, IHTMLTxtRange *range,
1947         LPWSTR unit, LONG cnt, LONG excnt)
1948 {
1949     LONG c = 0xdeadbeef;
1950     HRESULT hres;
1951
1952     hres = IHTMLTxtRange_moveStart(range, unit, cnt, &c);
1953     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1954     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1955 }
1956
1957 #define test_range_moveend(r,u,c,e) _test_range_moveend(__LINE__,r,u,c,e)
1958 static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1959 {
1960     LONG c = 0xdeadbeef;
1961     HRESULT hres;
1962
1963     hres = IHTMLTxtRange_moveEnd(range, unit, cnt, &c);
1964     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1965     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1966 }
1967
1968 #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
1969 static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
1970 {
1971     HRESULT hres;
1972     BSTR bstr = a2bstr(text);
1973
1974     hres = IHTMLTxtRange_put_text(range, bstr);
1975     ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
1976     SysFreeString(bstr);
1977     _test_range_text(line, range, NULL);
1978 }
1979
1980 #define test_range_inrange(r1,r2,b) _test_range_inrange(__LINE__,r1,r2,b)
1981 static void _test_range_inrange(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1982 {
1983     VARIANT_BOOL b;
1984     HRESULT hres;
1985
1986     b = 0xe0e0;
1987     hres = IHTMLTxtRange_inRange(range1, range2, &b);
1988     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1989     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1990 }
1991
1992 #define test_range_isequal(r1,r2,b) _test_range_isequal(__LINE__,r1,r2,b)
1993 static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1994 {
1995     VARIANT_BOOL b;
1996     HRESULT hres;
1997
1998     b = 0xe0e0;
1999     hres = IHTMLTxtRange_isEqual(range1, range2, &b);
2000     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
2001     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
2002
2003     b = 0xe0e0;
2004     hres = IHTMLTxtRange_isEqual(range2, range1, &b);
2005     ok_(__FILE__,line) (hres == S_OK, "(2->1) isEqual failed: %08x\n", hres);
2006     ok_(__FILE__,line) (b == exb, "(2->1) b=%x, expected %x\n", b, exb);
2007
2008     if(exb) {
2009         test_range_inrange(range1, range2, VARIANT_TRUE);
2010         test_range_inrange(range2, range1, VARIANT_TRUE);
2011     }
2012 }
2013
2014 #define test_range_parent(r,t) _test_range_parent(__LINE__,r,t)
2015 static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t type)
2016 {
2017     IHTMLElement *elem;
2018     HRESULT hres;
2019
2020     hres = IHTMLTxtRange_parentElement(range, &elem);
2021     ok_(__FILE__,line) (hres == S_OK, "parentElement failed: %08x\n", hres);
2022
2023     _test_elem_type(line, (IUnknown*)elem, type);
2024
2025     IHTMLElement_Release(elem);
2026 }
2027
2028 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
2029 static void _test_elem_collection(unsigned line, IUnknown *unk,
2030         const elem_type_t *elem_types, LONG exlen)
2031 {
2032     IHTMLElementCollection *col;
2033     LONG len;
2034     DWORD i;
2035     VARIANT name, index;
2036     IDispatch *disp, *disp2;
2037     HRESULT hres;
2038
2039     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col);
2040     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres);
2041
2042     test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]");
2043
2044     hres = IHTMLElementCollection_get_length(col, &len);
2045     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
2046     ok_(__FILE__,line) (len == exlen, "len=%d, expected %d\n", len, exlen);
2047
2048     if(len > exlen)
2049         len = exlen;
2050
2051     V_VT(&index) = VT_EMPTY;
2052
2053     for(i=0; i<len; i++) {
2054         V_VT(&name) = VT_I4;
2055         V_I4(&name) = i;
2056         disp = (void*)0xdeadbeef;
2057         hres = IHTMLElementCollection_item(col, name, index, &disp);
2058         ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2059         ok_(__FILE__,line) (disp != NULL, "item returned NULL\n");
2060         if(FAILED(hres) || !disp)
2061             continue;
2062
2063         _test_elem_type(line, (IUnknown*)disp, elem_types[i]);
2064
2065         if(!i) {
2066             V_VT(&name) = VT_UINT;
2067             V_I4(&name) = 0;
2068             disp2 = (void*)0xdeadbeef;
2069             hres = IHTMLElementCollection_item(col, name, index, &disp2);
2070             ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2071             ok_(__FILE__,line) (iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
2072             if(disp2)
2073                 IDispatch_Release(disp2);
2074         }
2075
2076         IDispatch_Release(disp);
2077     }
2078
2079     V_VT(&name) = VT_I4;
2080     V_I4(&name) = len;
2081     disp = (void*)0xdeadbeef;
2082     hres = IHTMLElementCollection_item(col, name, index, &disp);
2083     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2084     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2085
2086     V_VT(&name) = VT_I4;
2087     V_I4(&name) = -1;
2088     disp = (void*)0xdeadbeef;
2089     hres = IHTMLElementCollection_item(col, name, index, &disp);
2090     ok_(__FILE__,line) (hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
2091     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2092
2093     IHTMLElementCollection_Release(col);
2094 }
2095
2096 #define test_elem_all(c,t,l) _test_elem_all(__LINE__,c,t,l)
2097 static void _test_elem_all(unsigned line, IUnknown *unk, const elem_type_t *elem_types, LONG exlen)
2098 {
2099     IHTMLElement *elem = _get_elem_iface(line, unk);
2100     IDispatch *disp;
2101     HRESULT hres;
2102
2103     hres = IHTMLElement_get_all(elem, &disp);
2104     IHTMLElement_Release(elem);
2105     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2106
2107     _test_elem_collection(line, (IUnknown*)disp, elem_types, exlen);
2108     IDispatch_Release(disp);
2109 }
2110
2111 #define test_doc_all(a,b,c) _test_doc_all(__LINE__,a,b,c)
2112 static void _test_doc_all(unsigned line, IHTMLDocument2 *doc, const elem_type_t *elem_types, LONG exlen)
2113 {
2114     IHTMLElementCollection *col;
2115     HRESULT hres;
2116
2117     hres = IHTMLDocument2_get_all(doc, &col);
2118     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2119
2120     _test_elem_collection(line, (IUnknown*)col, elem_types, exlen);
2121     IHTMLElementCollection_Release(col);
2122 }
2123
2124 #define test_elem_getelembytag(a,b,c,d) _test_elem_getelembytag(__LINE__,a,b,c,d)
2125 static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t type, LONG exlen, IHTMLElement **ret)
2126 {
2127     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2128     IHTMLElementCollection *col = NULL;
2129     elem_type_t *types = NULL;
2130     BSTR tmp;
2131     int i;
2132     HRESULT hres;
2133
2134     tmp = a2bstr(elem_type_infos[type].tag);
2135     hres = IHTMLElement2_getElementsByTagName(elem, tmp, &col);
2136     SysFreeString(tmp);
2137     IHTMLElement2_Release(elem);
2138     ok_(__FILE__,line) (hres == S_OK, "getElementByTagName failed: %08x\n", hres);
2139     ok_(__FILE__,line) (col != NULL, "col == NULL\n");
2140
2141     if(exlen) {
2142         types = HeapAlloc(GetProcessHeap(), 0, exlen*sizeof(elem_type_t));
2143         for(i=0; i<exlen; i++)
2144             types[i] = type;
2145     }
2146
2147     _test_elem_collection(line, (IUnknown*)col, types, exlen);
2148
2149     HeapFree(GetProcessHeap(), 0, types);
2150
2151     if(ret) {
2152         IDispatch *disp;
2153         VARIANT v;
2154
2155         V_VT(&v) = VT_I4;
2156         V_I4(&v) = 0;
2157         disp = NULL;
2158         hres = IHTMLElementCollection_item(col, v, v, &disp);
2159         ok(hres == S_OK, "item failed: %08x\n", hres);
2160         ok(disp != NULL, "disp == NULL\n");
2161         *ret = _get_elem_iface(line, (IUnknown*)disp);
2162         IDispatch_Release(disp);
2163     }
2164
2165     IHTMLElementCollection_Release(col);
2166 }
2167
2168 #define test_elem_innertext(e,t) _test_elem_innertext(__LINE__,e,t)
2169 static void _test_elem_innertext(unsigned line, IHTMLElement *elem, const char *extext)
2170 {
2171     BSTR text = NULL;
2172     HRESULT hres;
2173
2174     hres = IHTMLElement_get_innerText(elem, &text);
2175     ok_(__FILE__,line) (hres == S_OK, "get_innerText failed: %08x\n", hres);
2176     if(extext)
2177         ok_(__FILE__,line) (!strcmp_wa(text, extext), "get_innerText returned %s expected %s\n",
2178                             wine_dbgstr_w(text), extext);
2179     else
2180         ok_(__FILE__,line) (!text, "get_innerText returned %s expected NULL\n", wine_dbgstr_w(text));
2181     SysFreeString(text);
2182 }
2183
2184 #define test_elem_set_innertext(e,t) _test_elem_set_innertext(__LINE__,e,t)
2185 static void _test_elem_set_innertext(unsigned line, IHTMLElement *elem, const char *text)
2186 {
2187     IHTMLDOMChildrenCollection *col;
2188     BSTR str;
2189     HRESULT hres;
2190
2191     str = a2bstr(text);
2192     hres = IHTMLElement_put_innerText(elem, str);
2193     ok_(__FILE__,line) (hres == S_OK, "put_innerText failed: %08x\n", hres);
2194     SysFreeString(str);
2195
2196     _test_elem_innertext(line, elem, text);
2197
2198
2199     col = _get_child_nodes(line, (IUnknown*)elem);
2200     ok(col != NULL, "col == NULL\n");
2201     if(col) {
2202         LONG length = 0, type;
2203         IHTMLDOMNode *node;
2204
2205         hres = IHTMLDOMChildrenCollection_get_length(col, &length);
2206         ok(hres == S_OK, "get_length failed: %08x\n", hres);
2207         ok(length == 1, "length = %d\n", length);
2208
2209         node = _get_child_item(line, col, 0);
2210         ok(node != NULL, "node == NULL\n");
2211         if(node) {
2212             type = _get_node_type(line, (IUnknown*)node);
2213             ok(type == 3, "type=%d\n", type);
2214             IHTMLDOMNode_Release(node);
2215         }
2216
2217         IHTMLDOMChildrenCollection_Release(col);
2218     }
2219
2220 }
2221
2222 #define test_elem_innerhtml(e,t) _test_elem_innerhtml(__LINE__,e,t)
2223 static void _test_elem_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2224 {
2225     IHTMLElement *elem = _get_elem_iface(line, unk);
2226     BSTR html;
2227     HRESULT hres;
2228
2229     hres = IHTMLElement_get_innerHTML(elem, &html);
2230     ok_(__FILE__,line)(hres == S_OK, "get_innerHTML failed: %08x\n", hres);
2231     if(inner_html)
2232         ok_(__FILE__,line)(!strcmp_wa(html, inner_html), "unexpected innerHTML: %s\n", wine_dbgstr_w(html));
2233     else
2234         ok_(__FILE__,line)(!html, "innerHTML = %s\n", wine_dbgstr_w(html));
2235
2236     IHTMLElement_Release(elem);
2237     SysFreeString(html);
2238 }
2239
2240 #define test_elem_set_innerhtml(e,t) _test_elem_set_innerhtml(__LINE__,e,t)
2241 static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2242 {
2243     IHTMLElement *elem = _get_elem_iface(line, unk);
2244     BSTR html;
2245     HRESULT hres;
2246
2247     html = a2bstr(inner_html);
2248     hres = IHTMLElement_put_innerHTML(elem, html);
2249     ok_(__FILE__,line)(hres == S_OK, "put_innerHTML failed: %08x\n", hres);
2250
2251     IHTMLElement_Release(elem);
2252     SysFreeString(html);
2253 }
2254
2255 #define test_elem_set_outerhtml(e,t) _test_elem_set_outerhtml(__LINE__,e,t)
2256 static void _test_elem_set_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2257 {
2258     IHTMLElement *elem = _get_elem_iface(line, unk);
2259     BSTR html;
2260     HRESULT hres;
2261
2262     html = a2bstr(outer_html);
2263     hres = IHTMLElement_put_outerHTML(elem, html);
2264     ok_(__FILE__,line)(hres == S_OK, "put_outerHTML failed: %08x\n", hres);
2265
2266     IHTMLElement_Release(elem);
2267     SysFreeString(html);
2268 }
2269
2270 #define test_elem_outerhtml(e,t) _test_elem_outerhtml(__LINE__,e,t)
2271 static void _test_elem_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2272 {
2273     IHTMLElement *elem = _get_elem_iface(line, unk);
2274     BSTR html;
2275     HRESULT hres;
2276
2277     hres = IHTMLElement_get_outerHTML(elem, &html);
2278     ok_(__FILE__,line)(hres == S_OK, "get_outerHTML failed: %08x\n", hres);
2279     ok_(__FILE__,line)(!strcmp_wa(html, outer_html), "outerHTML = '%s', expected '%s'\n", wine_dbgstr_w(html), outer_html);
2280
2281     IHTMLElement_Release(elem);
2282     SysFreeString(html);
2283 }
2284
2285 #define test_elem_contains(a,b,c) _test_elem_contains(__LINE__,a,b,c)
2286 static void _test_elem_contains(unsigned line, IHTMLElement *elem, IHTMLElement *elem2, VARIANT_BOOL exval)
2287 {
2288     VARIANT_BOOL b;
2289     HRESULT hres;
2290
2291     b = 100;
2292     hres = IHTMLElement_contains(elem, elem2, &b);
2293     ok_(__FILE__,line)(hres == S_OK, "contains failed: %08x\n", hres);
2294     ok_(__FILE__,line)(b == exval, "contains returned %x, expected %x\n", b, exval);
2295 }
2296
2297 #define get_first_child(n) _get_first_child(__LINE__,n)
2298 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
2299 {
2300     IHTMLDOMNode *node = _get_node_iface(line, unk);
2301     IHTMLDOMNode *child = NULL;
2302     HRESULT hres;
2303
2304     hres = IHTMLDOMNode_get_firstChild(node, &child);
2305     IHTMLDOMNode_Release(node);
2306     ok_(__FILE__,line) (hres == S_OK, "get_firstChild failed: %08x\n", hres);
2307
2308     return child;
2309 }
2310
2311 #define test_node_has_child(u,b) _test_node_has_child(__LINE__,u,b)
2312 static void _test_node_has_child(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2313 {
2314     IHTMLDOMNode *node = _get_node_iface(line, unk);
2315     VARIANT_BOOL b = 0xdead;
2316     HRESULT hres;
2317
2318     hres = IHTMLDOMNode_hasChildNodes(node, &b);
2319     ok_(__FILE__,line) (hres == S_OK, "hasChildNodes failed: %08x\n", hres);
2320     ok_(__FILE__,line) (b == exb, "hasChildNodes=%x, expected %x\n", b, exb);
2321
2322     IHTMLDOMNode_Release(node);
2323 }
2324
2325 #define test_node_get_parent(u) _test_node_get_parent(__LINE__,u)
2326 static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
2327 {
2328     IHTMLDOMNode *node = _get_node_iface(line, unk);
2329     IHTMLDOMNode *parent;
2330     HRESULT hres;
2331
2332     hres = IHTMLDOMNode_get_parentNode(node, &parent);
2333     IHTMLDOMNode_Release(node);
2334     ok_(__FILE__,line) (hres == S_OK, "get_parentNode failed: %08x\n", hres);
2335
2336     return parent;
2337 }
2338
2339 #define node_get_next(u) _node_get_next(__LINE__,u)
2340 static IHTMLDOMNode *_node_get_next(unsigned line, IUnknown *unk)
2341 {
2342     IHTMLDOMNode *node = _get_node_iface(line, unk);
2343     IHTMLDOMNode *next;
2344     HRESULT hres;
2345
2346     hres = IHTMLDOMNode_get_nextSibling(node, &next);
2347     IHTMLDOMNode_Release(node);
2348     ok_(__FILE__,line) (hres == S_OK, "get_nextSiblibg failed: %08x\n", hres);
2349
2350     return next;
2351 }
2352
2353 #define node_get_prev(u) _node_get_prev(__LINE__,u)
2354 static IHTMLDOMNode *_node_get_prev(unsigned line, IUnknown *unk)
2355 {
2356     IHTMLDOMNode *node = _get_node_iface(line, unk);
2357     IHTMLDOMNode *prev;
2358     HRESULT hres;
2359
2360     hres = IHTMLDOMNode_get_previousSibling(node, &prev);
2361     IHTMLDOMNode_Release(node);
2362     ok_(__FILE__,line) (hres == S_OK, "get_previousSibling failed: %08x\n", hres);
2363
2364     return prev;
2365 }
2366
2367 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
2368 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
2369 {
2370     IHTMLElement *elem = _get_elem_iface(line, unk);
2371     IHTMLElement *parent;
2372     HRESULT hres;
2373
2374     hres = IHTMLElement_get_parentElement(elem, &parent);
2375     IHTMLElement_Release(elem);
2376     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
2377
2378     return parent;
2379 }
2380
2381 #define test_elem3_get_disabled(i,b) _test_elem3_get_disabled(__LINE__,i,b)
2382 static void _test_elem3_get_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2383 {
2384     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2385     VARIANT_BOOL disabled = 100;
2386     HRESULT hres;
2387
2388     if (!elem3) return;
2389     hres = IHTMLElement3_get_disabled(elem3, &disabled);
2390     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2391     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2392     IHTMLElement3_Release(elem3);
2393 }
2394
2395 #define test_elem3_set_disabled(i,b) _test_elem3_set_disabled(__LINE__,i,b)
2396 static void _test_elem3_set_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL b)
2397 {
2398     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2399     HRESULT hres;
2400
2401     if (!elem3) return;
2402     hres = IHTMLElement3_put_disabled(elem3, b);
2403     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2404
2405     IHTMLElement3_Release(elem3);
2406     _test_elem3_get_disabled(line, unk, b);
2407 }
2408
2409 #define test_select_get_disabled(i,b) _test_select_get_disabled(__LINE__,i,b)
2410 static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exb)
2411 {
2412     VARIANT_BOOL disabled = 100;
2413     HRESULT hres;
2414
2415     hres = IHTMLSelectElement_get_disabled(select, &disabled);
2416     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2417     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2418
2419     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
2420 }
2421
2422 #define test_text_length(u,l) _test_text_length(__LINE__,u,l)
2423 static void _test_text_length(unsigned line, IUnknown *unk, LONG l)
2424 {
2425     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2426     LONG length;
2427     HRESULT hres;
2428
2429     hres = IHTMLDOMTextNode_get_length(text, &length);
2430     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
2431     ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l);
2432     IHTMLDOMTextNode_Release(text);
2433 }
2434
2435 #define test_text_data(a,b) _test_text_data(__LINE__,a,b)
2436 static void _test_text_data(unsigned line, IUnknown *unk, const char *exdata)
2437 {
2438     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2439     BSTR str;
2440     HRESULT hres;
2441
2442     hres = IHTMLDOMTextNode_get_data(text, &str);
2443     ok_(__FILE__,line)(hres == S_OK, "get_data failed: %08x\n", hres);
2444     ok_(__FILE__,line)(!strcmp_wa(str, exdata), "data = %s, expected %s\n", wine_dbgstr_w(str), exdata);
2445     IHTMLDOMTextNode_Release(text);
2446     SysFreeString(str);
2447 }
2448
2449 #define set_text_data(a,b) _set_text_data(__LINE__,a,b)
2450 static void _set_text_data(unsigned line, IUnknown *unk, const char *data)
2451 {
2452     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2453     BSTR str = a2bstr(data);
2454     HRESULT hres;
2455
2456     hres = IHTMLDOMTextNode_put_data(text, str);
2457     ok_(__FILE__,line)(hres == S_OK, "get_data failed: %08x\n", hres);
2458     IHTMLDOMTextNode_Release(text);
2459     SysFreeString(str);
2460 }
2461
2462 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
2463 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
2464 {
2465     HRESULT hres;
2466
2467     hres = IHTMLSelectElement_put_disabled(select, b);
2468     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2469
2470     _test_select_get_disabled(line, select, b);
2471 }
2472
2473 #define elem_get_scroll_height(u) _elem_get_scroll_height(__LINE__,u)
2474 static LONG _elem_get_scroll_height(unsigned line, IUnknown *unk)
2475 {
2476     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2477     IHTMLTextContainer *txtcont;
2478     LONG l = -1, l2 = -1;
2479     HRESULT hres;
2480
2481     hres = IHTMLElement2_get_scrollHeight(elem, &l);
2482     ok_(__FILE__,line) (hres == S_OK, "get_scrollHeight failed: %08x\n", hres);
2483     IHTMLElement2_Release(elem);
2484
2485     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2486     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2487
2488     hres = IHTMLTextContainer_get_scrollHeight(txtcont, &l2);
2489     IHTMLTextContainer_Release(txtcont);
2490     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollHeight failed: %d\n", l2);
2491     ok_(__FILE__,line) (l == l2, "unexpected height %d, expected %d\n", l2, l);
2492
2493     return l;
2494 }
2495
2496 #define elem_get_scroll_width(u) _elem_get_scroll_width(__LINE__,u)
2497 static LONG _elem_get_scroll_width(unsigned line, IUnknown *unk)
2498 {
2499     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2500     IHTMLTextContainer *txtcont;
2501     LONG l = -1, l2 = -1;
2502     HRESULT hres;
2503
2504     hres = IHTMLElement2_get_scrollWidth(elem, &l);
2505     ok_(__FILE__,line) (hres == S_OK, "get_scrollWidth failed: %08x\n", hres);
2506     IHTMLElement2_Release(elem);
2507
2508     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2509     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2510
2511     hres = IHTMLTextContainer_get_scrollWidth(txtcont, &l2);
2512     IHTMLTextContainer_Release(txtcont);
2513     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollWidth failed: %d\n", l2);
2514     ok_(__FILE__,line) (l == l2, "unexpected width %d, expected %d\n", l2, l);
2515
2516     return l;
2517 }
2518
2519 #define elem_get_scroll_top(u) _elem_get_scroll_top(__LINE__,u)
2520 static LONG _elem_get_scroll_top(unsigned line, IUnknown *unk)
2521 {
2522     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2523     IHTMLTextContainer *txtcont;
2524     LONG l = -1, l2 = -1;
2525     HRESULT hres;
2526
2527     hres = IHTMLElement2_get_scrollTop(elem, &l);
2528     ok_(__FILE__,line) (hres == S_OK, "get_scrollTop failed: %08x\n", hres);
2529     IHTMLElement2_Release(elem);
2530
2531     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2532     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2533
2534     hres = IHTMLTextContainer_get_scrollTop(txtcont, &l2);
2535     IHTMLTextContainer_Release(txtcont);
2536     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollTop failed: %d\n", l2);
2537     ok_(__FILE__,line) (l == l2, "unexpected top %d, expected %d\n", l2, l);
2538
2539     return l;
2540 }
2541
2542 #define elem_get_scroll_left(u) _elem_get_scroll_left(__LINE__,u)
2543 static void _elem_get_scroll_left(unsigned line, IUnknown *unk)
2544 {
2545     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2546     IHTMLTextContainer *txtcont;
2547     LONG l = -1, l2 = -1;
2548     HRESULT hres;
2549
2550     hres = IHTMLElement2_get_scrollLeft(elem, NULL);
2551     ok(hres == E_INVALIDARG, "expect E_INVALIDARG got 0x%08x\n", hres);
2552
2553     hres = IHTMLElement2_get_scrollLeft(elem, &l);
2554     ok(hres == S_OK, "get_scrollTop failed: %08x\n", hres);
2555     IHTMLElement2_Release(elem);
2556
2557     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2558     ok(hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2559
2560     hres = IHTMLTextContainer_get_scrollLeft(txtcont, &l2);
2561     IHTMLTextContainer_Release(txtcont);
2562     ok(hres == S_OK, "IHTMLTextContainer::get_scrollLeft failed: %d\n", l2);
2563     ok(l == l2, "unexpected left %d, expected %d\n", l2, l);
2564 }
2565
2566 #define test_img_src(a,b,c) _test_img_src(__LINE__,a,b,c)
2567 static void _test_img_src(unsigned line, IUnknown *unk, const char *exsrc, const char *broken_src)
2568 {
2569     IHTMLImgElement *img = _get_img_iface(line, unk);
2570     BSTR src;
2571     HRESULT hres;
2572
2573     hres = IHTMLImgElement_get_src(img, &src);
2574     IHTMLImgElement_Release(img);
2575     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
2576     ok_(__FILE__,line) (!strcmp_wa(src, exsrc) || (broken_src && broken(!strcmp_wa(src, broken_src))),
2577         "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
2578     SysFreeString(src);
2579 }
2580
2581 #define test_img_set_src(u,s) _test_img_set_src(__LINE__,u,s)
2582 static void _test_img_set_src(unsigned line, IUnknown *unk, const char *src)
2583 {
2584     IHTMLImgElement *img = _get_img_iface(line, unk);
2585     BSTR tmp;
2586     HRESULT hres;
2587
2588     tmp = a2bstr(src);
2589     hres = IHTMLImgElement_put_src(img, tmp);
2590     IHTMLImgElement_Release(img);
2591     SysFreeString(tmp);
2592     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
2593 }
2594
2595 #define test_img_alt(u,a) _test_img_alt(__LINE__,u,a)
2596 static void _test_img_alt(unsigned line, IUnknown *unk, const char *exalt)
2597 {
2598     IHTMLImgElement *img = _get_img_iface(line, unk);
2599     BSTR alt;
2600     HRESULT hres;
2601
2602     hres = IHTMLImgElement_get_alt(img, &alt);
2603     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
2604     if(exalt)
2605         ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "inexopected alt %s\n", wine_dbgstr_w(alt));
2606     else
2607         ok_(__FILE__,line) (!alt, "alt != NULL\n");
2608     SysFreeString(alt);
2609 }
2610
2611 #define test_img_set_alt(u,a) _test_img_set_alt(__LINE__,u,a)
2612 static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
2613 {
2614     IHTMLImgElement *img = _get_img_iface(line, unk);
2615     BSTR tmp;
2616     HRESULT hres;
2617
2618     tmp = a2bstr(alt);
2619     hres = IHTMLImgElement_put_alt(img, tmp);
2620     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
2621     SysFreeString(tmp);
2622
2623     _test_img_alt(line, unk, alt);
2624 }
2625
2626 #define test_img_name(u, c) _test_img_name(__LINE__,u, c)
2627 static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue)
2628 {
2629     IHTMLImgElement *img = _get_img_iface(line, unk);
2630     BSTR sName;
2631     HRESULT hres;
2632
2633     hres = IHTMLImgElement_get_name(img, &sName);
2634     ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres);
2635     ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName));
2636     IHTMLImgElement_Release(img);
2637     SysFreeString(sName);
2638 }
2639
2640 #define test_img_complete(a,b) _test_img_complete(__LINE__,a,b)
2641 static void _test_img_complete(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
2642 {
2643     IHTMLImgElement *img = _get_img_iface(line, (IUnknown*)elem);
2644     VARIANT_BOOL b = 100;
2645     HRESULT hres;
2646
2647     hres = IHTMLImgElement_get_complete(img, &b);
2648     ok_(__FILE__,line) (hres == S_OK, "get_complete failed: %08x\n", hres);
2649     ok_(__FILE__,line) (b == exb, "complete = %x, expected %x\n", b, exb);
2650     IHTMLImgElement_Release(img);
2651 }
2652
2653 static void test_dynamic_properties(IHTMLElement *elem)
2654 {
2655     static const WCHAR attr1W[] = {'a','t','t','r','1',0};
2656     IDispatchEx *dispex;
2657     BSTR name, attr1 = SysAllocString(attr1W);
2658     VARIANT_BOOL succ;
2659     VARIANT val;
2660     int checked_no = 0;
2661     DISPID id = DISPID_STARTENUM;
2662     HRESULT hres;
2663
2664     hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
2665     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2666
2667     hres = IHTMLElement_removeAttribute(elem, attr1, 0, &succ);
2668     ok(hres == S_OK, "removeAttribute failed: %08x\n", hres);
2669     ok(succ, "removeAttribute set succ to FALSE\n");
2670
2671     while(1) {
2672         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, id, &id);
2673         ok(hres==S_OK || hres==S_FALSE, "GetNextDispID failed: %08x\n", hres);
2674         if(hres != S_OK)
2675             break;
2676
2677         hres = IDispatchEx_GetMemberName(dispex, id, &name);
2678         ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
2679
2680         if(!strcmp_wa(name, "attr1"))
2681             ok(0, "attr1 should be removed\n");
2682         else if(!strcmp_wa(name, "attr2") || !strcmp_wa(name, "attr3"))
2683             checked_no++;
2684         SysFreeString(name);
2685     }
2686     ok(checked_no == 2, "checked_no=%d, expected 2\n", checked_no);
2687     IDispatchEx_Release(dispex);
2688
2689     V_VT(&val) = VT_BSTR;
2690     V_BSTR(&val) = attr1;
2691     hres = IHTMLElement_setAttribute(elem, attr1, val, 0);
2692     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
2693     SysFreeString(attr1);
2694 }
2695
2696 #define test_attr_node_name(a,b) _test_attr_node_name(__LINE__,a,b)
2697 static void _test_attr_node_name(unsigned line, IHTMLDOMAttribute *attr, const char *exname)
2698 {
2699     BSTR str;
2700     HRESULT hres;
2701
2702     hres = IHTMLDOMAttribute_get_nodeName(attr, &str);
2703     ok_(__FILE__,line)(hres == S_OK, "get_nodeName failed: %08x\n", hres);
2704     ok_(__FILE__,line)(!strcmp_wa(str, exname), "node name is %s, expected %s\n", wine_dbgstr_w(str), exname);
2705     SysFreeString(str);
2706 }
2707
2708 static void test_attr_collection_disp(IDispatch *disp)
2709 {
2710     IDispatchEx *dispex;
2711     IHTMLDOMAttribute *attr;
2712     DISPPARAMS dp = {NULL, NULL, 0, 0};
2713     VARIANT var;
2714     EXCEPINFO ei;
2715     DISPID id;
2716     BSTR bstr;
2717     HRESULT hres;
2718
2719     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2720     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2721
2722     bstr = a2bstr("0");
2723     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
2724     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2725     SysFreeString(bstr);
2726
2727     VariantInit(&var);
2728     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2729     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2730     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2731     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
2732     VariantClear(&var);
2733
2734     bstr = a2bstr("attr1");
2735     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
2736     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2737     SysFreeString(bstr);
2738
2739     VariantInit(&var);
2740     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2741     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2742     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2743     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
2744     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLDOMAttribute, (void**)&attr);
2745     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2746
2747     test_attr_node_name(attr, "attr1");
2748
2749     IHTMLDOMAttribute_Release(attr);
2750     VariantClear(&var);
2751
2752     IDispatchEx_Release(dispex);
2753 }
2754
2755 static void test_attr_collection(IHTMLElement *elem)
2756 {
2757     static const WCHAR testW[] = {'t','e','s','t',0};
2758
2759     IHTMLDOMNode *node;
2760     IDispatch *disp, *attr;
2761     IHTMLDOMAttribute *dom_attr;
2762     IHTMLAttributeCollection *attr_col;
2763     BSTR name = SysAllocString(testW);
2764     VARIANT id, val;
2765     LONG i, len, checked;
2766     HRESULT hres;
2767
2768     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLDOMNode, (void**)&node);
2769     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2770
2771     hres = IHTMLDOMNode_get_attributes(node, &disp);
2772     ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
2773
2774     hres = IHTMLDOMNode_get_attributes(node, &attr);
2775     ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
2776     ok(iface_cmp((IUnknown*)disp, (IUnknown*)attr), "disp != attr\n");
2777     IDispatch_Release(attr);
2778     IHTMLDOMNode_Release(node);
2779
2780     hres = IDispatch_QueryInterface(disp, &IID_IHTMLAttributeCollection, (void**)&attr_col);
2781     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2782
2783     hres = IHTMLAttributeCollection_get_length(attr_col, &i);
2784     ok(hres == S_OK, "get_length failed: %08x\n", hres);
2785
2786     V_VT(&val) = VT_I4;
2787     V_I4(&val) = 1;
2788     hres = IHTMLElement_setAttribute(elem, name, val, 0);
2789     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
2790     SysFreeString(name);
2791
2792     hres = IHTMLAttributeCollection_get_length(attr_col, &len);
2793     ok(hres == S_OK, "get_length failed: %08x\n", hres);
2794     ok(len == i+1, "get_length returned %d, expected %d\n", len, i+1);
2795
2796     checked = 0;
2797     for(i=0; i<len; i++) {
2798         V_VT(&id) = VT_I4;
2799         V_I4(&id) = i;
2800         hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
2801         ok(hres == S_OK, "%d) item failed: %08x\n", i, hres);
2802
2803         hres = IDispatch_QueryInterface(attr, &IID_IHTMLDOMAttribute, (void**)&dom_attr);
2804         ok(hres == S_OK, "%d) QueryInterface failed: %08x\n", i, hres);
2805         IDispatch_Release(attr);
2806
2807         hres = IHTMLDOMAttribute_get_nodeName(dom_attr, &name);
2808         ok(hres == S_OK, "%d) get_nodeName failed: %08x\n", i, hres);
2809
2810         if(!strcmp_wa(name, "id")) {
2811             checked++;
2812             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2813             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2814             ok(V_VT(&val) == VT_BSTR, "id: V_VT(&val) = %d\n", V_VT(&val));
2815             ok(!strcmp_wa(V_BSTR(&val), "attr"), "id: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
2816         } else if(!strcmp_wa(name, "attr1")) {
2817             checked++;
2818             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2819             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2820             ok(V_VT(&val) == VT_BSTR, "attr1: V_VT(&val) = %d\n", V_VT(&val));
2821             ok(!strcmp_wa(V_BSTR(&val), "attr1"), "attr1: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
2822         } else if(!strcmp_wa(name, "attr2")) {
2823             checked++;
2824             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2825             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2826             ok(V_VT(&val) == VT_BSTR, "attr2: V_VT(&val) = %d\n", V_VT(&val));
2827             ok(!V_BSTR(&val), "attr2: V_BSTR(&val) != NULL\n");
2828         } else if(!strcmp_wa(name, "attr3")) {
2829             checked++;
2830             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2831             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2832             ok(V_VT(&val) == VT_BSTR, "attr3: V_VT(&val) = %d\n", V_VT(&val));
2833             ok(!strcmp_wa(V_BSTR(&val), "attr3"), "attr3: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
2834         } else if(!strcmp_wa(name, "test")) {
2835             checked++;
2836             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2837             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2838             ok(V_VT(&val) == VT_I4, "test: V_VT(&val) = %d\n", V_VT(&val));
2839             ok(V_I4(&val) == 1, "test: V_I4(&val) = %d\n", V_I4(&val));
2840         }
2841
2842         IHTMLDOMAttribute_Release(dom_attr);
2843         SysFreeString(name);
2844         VariantClear(&val);
2845     }
2846     ok(checked==5, "invalid number of specified attributes (%d)\n", checked);
2847
2848     V_I4(&id) = len;
2849     hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
2850     ok(hres == E_INVALIDARG, "item failed: %08x\n", hres);
2851
2852     V_VT(&id) = VT_BSTR;
2853     V_BSTR(&id) = a2bstr("nonexisting");
2854     hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
2855     ok(hres == E_INVALIDARG, "item failed: %08x\n", hres);
2856     VariantClear(&id);
2857
2858     test_attr_collection_disp(disp);
2859
2860     IDispatch_Release(disp);
2861     IHTMLAttributeCollection_Release(attr_col);
2862 }
2863
2864 #define test_attr_specified(a,b) _test_attr_specified(__LINE__,a,b)
2865 static void _test_attr_specified(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected)
2866 {
2867     VARIANT_BOOL specified;
2868     HRESULT hres;
2869
2870     hres = IHTMLDOMAttribute_get_specified(attr, &specified);
2871     ok_(__FILE__,line)(hres == S_OK, "get_specified failed: %08x\n", hres);
2872     ok_(__FILE__,line)(specified == expected, "specified = %x, expected %x\n", specified, expected);
2873 }
2874
2875 #define test_input_type(i,t) _test_input_type(__LINE__,i,t)
2876 static void _test_input_type(unsigned line, IHTMLInputElement *input, const char *extype)
2877 {
2878     BSTR type;
2879     HRESULT hres;
2880
2881     hres = IHTMLInputElement_get_type(input, &type);
2882     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
2883     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
2884     SysFreeString(type);
2885 }
2886
2887 #define test_input_name(u, c) _test_input_name(__LINE__,u, c)
2888 static void _test_input_name(unsigned line, IHTMLInputElement *input, const char *exname)
2889 {
2890     BSTR name = (BSTR)0xdeadbeef;
2891     HRESULT hres;
2892
2893     hres = IHTMLInputElement_get_name(input, &name);
2894     ok_(__FILE__,line) (hres == S_OK, "get_name failed: %08x\n", hres);
2895     if(exname)
2896         ok_(__FILE__,line) (!strcmp_wa (name, exname), "name=%s, expected %s\n", wine_dbgstr_w(name), exname);
2897     else
2898         ok_(__FILE__,line) (!name, "name=%p, expected NULL\n", name);
2899     SysFreeString(name);
2900 }
2901
2902 #define test_input_set_name(u, c) _test_input_set_name(__LINE__,u, c)
2903 static void _test_input_set_name(unsigned line, IHTMLInputElement *input, const char *name)
2904 {
2905     BSTR tmp = a2bstr(name);
2906     HRESULT hres;
2907
2908     hres = IHTMLInputElement_put_name(input, tmp);
2909     ok_(__FILE__,line) (hres == S_OK, "put_name failed: %08x\n", hres);
2910     SysFreeString(tmp);
2911
2912     _test_input_name(line, input, name);
2913 }
2914
2915 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
2916 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2917 {
2918     VARIANT_BOOL disabled = 100;
2919     HRESULT hres;
2920
2921     hres = IHTMLInputElement_get_disabled(input, &disabled);
2922     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2923     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2924
2925     _test_elem3_get_disabled(line, (IUnknown*)input, exb);
2926 }
2927
2928 #define test_input_set_disabled(i,b) _test_input_set_disabled(__LINE__,i,b)
2929 static void _test_input_set_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2930 {
2931     HRESULT hres;
2932
2933     hres = IHTMLInputElement_put_disabled(input, b);
2934     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2935
2936     _test_input_get_disabled(line, input, b);
2937 }
2938
2939 #define test_input_get_defaultchecked(i,b) _test_input_get_defaultchecked(__LINE__,i,b)
2940 static void _test_input_get_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2941 {
2942     VARIANT_BOOL checked = 100;
2943     HRESULT hres;
2944
2945     hres = IHTMLInputElement_get_defaultChecked(input, &checked);
2946     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
2947     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
2948 }
2949
2950 #define test_input_set_defaultchecked(i,b) _test_input_set_defaultchecked(__LINE__,i,b)
2951 static void _test_input_set_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2952 {
2953     HRESULT hres;
2954
2955     hres = IHTMLInputElement_put_defaultChecked(input, b);
2956     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
2957
2958     _test_input_get_defaultchecked(line, input, b);
2959 }
2960
2961 #define test_input_get_checked(i,b) _test_input_get_checked(__LINE__,i,b)
2962 static void _test_input_get_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2963 {
2964     VARIANT_BOOL checked = 100;
2965     HRESULT hres;
2966
2967     hres = IHTMLInputElement_get_checked(input, &checked);
2968     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
2969     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
2970 }
2971
2972 #define test_input_set_checked(i,b) _test_input_set_checked(__LINE__,i,b)
2973 static void _test_input_set_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2974 {
2975     HRESULT hres;
2976
2977     hres = IHTMLInputElement_put_checked(input, b);
2978     ok_(__FILE__,line) (hres == S_OK, "put_checked failed: %08x\n", hres);
2979
2980     _test_input_get_checked(line, input, b);
2981 }
2982
2983 #define test_input_maxlength(i,b) _test_input_maxlength(__LINE__,i,b)
2984 static void _test_input_maxlength(unsigned line, IHTMLInputElement *input, LONG exl)
2985 {
2986     LONG maxlength = 0xdeadbeef;
2987     HRESULT hres;
2988
2989     hres = IHTMLInputElement_get_maxLength(input, &maxlength);
2990     ok_(__FILE__,line) (hres == S_OK, "get_maxLength failed: %08x\n", hres);
2991     ok_(__FILE__,line) (maxlength == exl, "maxLength=%x, expected %d\n", maxlength, exl);
2992 }
2993
2994 #define test_input_set_maxlength(i,b) _test_input_set_maxlength(__LINE__,i,b)
2995 static void _test_input_set_maxlength(unsigned line, IHTMLInputElement *input, LONG l)
2996 {
2997     HRESULT hres;
2998
2999     hres = IHTMLInputElement_put_maxLength(input, l);
3000     ok_(__FILE__,line) (hres == S_OK, "put_maxLength failed: %08x\n", hres);
3001
3002     _test_input_maxlength(line, input, l);
3003 }
3004
3005 #define test_input_value(o,t) _test_input_value(__LINE__,o,t)
3006 static void _test_input_value(unsigned line, IUnknown *unk, const char *exval)
3007 {
3008     IHTMLInputElement *input;
3009     BSTR bstr;
3010     HRESULT hres;
3011
3012     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3013     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3014     if(FAILED(hres))
3015         return;
3016
3017     hres = IHTMLInputElement_get_value(input, &bstr);
3018     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
3019     if(exval)
3020         ok_(__FILE__,line) (!strcmp_wa(bstr, exval), "value=%s\n", wine_dbgstr_w(bstr));
3021     else
3022         ok_(__FILE__,line) (!bstr, "exval != NULL\n");
3023     SysFreeString(bstr);
3024     IHTMLInputElement_Release(input);
3025 }
3026
3027 #define test_input_put_value(o,v) _test_input_put_value(__LINE__,o,v)
3028 static void _test_input_put_value(unsigned line, IUnknown *unk, const char *val)
3029 {
3030     IHTMLInputElement *input;
3031     BSTR bstr;
3032     HRESULT hres;
3033
3034     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3035     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3036     if(FAILED(hres))
3037         return;
3038
3039     bstr = a2bstr(val);
3040     hres = IHTMLInputElement_put_value(input, bstr);
3041     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
3042     SysFreeString(bstr);
3043     IHTMLInputElement_Release(input);
3044
3045     _test_input_value(line, unk, val);
3046 }
3047
3048 #define test_input_defaultValue(o,t) _test_input_defaultValue(__LINE__,o,t)
3049 static void _test_input_defaultValue(unsigned line, IUnknown *unk, const char *exval)
3050 {
3051     IHTMLInputElement *input;
3052     BSTR str;
3053     HRESULT hres;
3054
3055     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3056     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3057     if(FAILED(hres))
3058         return;
3059
3060     hres = IHTMLInputElement_get_defaultValue(input, &str);
3061     ok_(__FILE__,line) (hres == S_OK, "get_defaultValue failed: %08x\n", hres);
3062     if(exval)
3063         ok_(__FILE__,line) (!strcmp_wa(str, exval), "defaultValue=%s\n", wine_dbgstr_w(str));
3064     else
3065         ok_(__FILE__,line) (!str, "exval != NULL\n");
3066     SysFreeString(str);
3067     IHTMLInputElement_Release(input);
3068 }
3069
3070 #define test_input_put_defaultValue(o,v) _test_input_put_defaultValue(__LINE__,o,v)
3071 static void _test_input_put_defaultValue(unsigned line, IUnknown *unk, const char *val)
3072 {
3073     IHTMLInputElement *input;
3074     BSTR str;
3075     HRESULT hres;
3076
3077     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3078     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3079     if(FAILED(hres))
3080         return;
3081
3082     str = a2bstr(val);
3083     hres = IHTMLInputElement_put_defaultValue(input, str);
3084     ok_(__FILE__,line) (hres == S_OK, "get_defaultValue failed: %08x\n", hres);
3085     SysFreeString(str);
3086     IHTMLInputElement_Release(input);
3087
3088     _test_input_defaultValue(line, unk, val);
3089 }
3090
3091 #define test_input_src(i,s) _test_input_src(__LINE__,i,s)
3092 static void _test_input_src(unsigned line, IHTMLInputElement *input, const char *exsrc)
3093 {
3094     BSTR src;
3095     HRESULT hres;
3096
3097     hres = IHTMLInputElement_get_src(input, &src);
3098     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
3099     if(exsrc)
3100         ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
3101     else
3102         ok_(__FILE__,line) (!src, "get_src returned %s expected NULL\n", wine_dbgstr_w(src));
3103     SysFreeString(src);
3104 }
3105
3106 #define test_input_set_src(u,s) _test_input_set_src(__LINE__,u,s)
3107 static void _test_input_set_src(unsigned line, IHTMLInputElement *input, const char *src)
3108 {
3109     BSTR tmp;
3110     HRESULT hres;
3111
3112     tmp = a2bstr(src);
3113     hres = IHTMLInputElement_put_src(input, tmp);
3114     SysFreeString(tmp);
3115     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
3116
3117     _test_input_src(line, input, src);
3118 }
3119
3120 #define test_elem_class(u,c) _test_elem_class(__LINE__,u,c)
3121 static void _test_elem_class(unsigned line, IUnknown *unk, const char *exclass)
3122 {
3123     IHTMLElement *elem = _get_elem_iface(line, unk);
3124     BSTR class = (void*)0xdeadbeef;
3125     HRESULT hres;
3126
3127     hres = IHTMLElement_get_className(elem, &class);
3128     IHTMLElement_Release(elem);
3129     ok_(__FILE__,line) (hres == S_OK, "get_className failed: %08x\n", hres);
3130     if(exclass)
3131         ok_(__FILE__,line) (!strcmp_wa(class, exclass), "unexpected className %s\n", wine_dbgstr_w(class));
3132     else
3133         ok_(__FILE__,line) (!class, "class != NULL\n");
3134     SysFreeString(class);
3135 }
3136
3137 #define test_elem_tabindex(u,i) _test_elem_tabindex(__LINE__,u,i)
3138 static void _test_elem_tabindex(unsigned line, IUnknown *unk, short exindex)
3139 {
3140     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
3141     short index = -3;
3142     HRESULT hres;
3143
3144     hres = IHTMLElement2_get_tabIndex(elem2, &index);
3145     IHTMLElement2_Release(elem2);
3146     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
3147     ok_(__FILE__,line) (index == exindex, "unexpected index %d\n", index);
3148 }
3149
3150 #define test_elem_set_tabindex(u,i) _test_elem_set_tabindex(__LINE__,u,i)
3151 static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index)
3152 {
3153     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
3154     HRESULT hres;
3155
3156     hres = IHTMLElement2_put_tabIndex(elem2, index);
3157     IHTMLElement2_Release(elem2);
3158     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
3159
3160     _test_elem_tabindex(line, unk, index);
3161 }
3162
3163 #define test_style_media(s,m) _test_style_media(__LINE__,s,m)
3164 static void _test_style_media(unsigned line, IUnknown *unk, const char *exmedia)
3165 {
3166     IHTMLStyleElement *style = _get_style_iface(line, unk);
3167     BSTR media;
3168     HRESULT hres;
3169
3170     hres = IHTMLStyleElement_get_media(style, &media);
3171     ok_(__FILE__,line)(hres == S_OK, "get_media failed: %08x\n", hres);
3172     if(exmedia)
3173         ok_(__FILE__,line)(!strcmp_wa(media, exmedia), "media = %s, expected %s\n", wine_dbgstr_w(media), exmedia);
3174     else
3175         ok_(__FILE__,line)(!media, "media = %s, expected NULL\n", wine_dbgstr_w(media));
3176
3177     IHTMLStyleElement_Release(style);
3178     SysFreeString(media);
3179 }
3180
3181 #define test_style_put_media(s,m) _test_style_put_media(__LINE__,s,m)
3182 static void _test_style_put_media(unsigned line, IUnknown *unk, const char *media)
3183 {
3184     IHTMLStyleElement *style = _get_style_iface(line, unk);
3185     BSTR str;
3186     HRESULT hres;
3187
3188     str = a2bstr(media);
3189     hres = IHTMLStyleElement_put_media(style, str);
3190     ok_(__FILE__,line)(hres == S_OK, "put_media failed: %08x\n", hres);
3191     IHTMLStyleElement_Release(style);
3192     SysFreeString(str);
3193
3194     _test_style_media(line, unk, media);
3195 }
3196
3197 #define test_style_type(s,m) _test_style_type(__LINE__,s,m)
3198 static void _test_style_type(unsigned line, IUnknown *unk, const char *extype)
3199 {
3200     IHTMLStyleElement *style = _get_style_iface(line, unk);
3201     BSTR type;
3202     HRESULT hres;
3203
3204     hres = IHTMLStyleElement_get_type(style, &type);
3205     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
3206     if(extype)
3207         ok_(__FILE__,line)(!strcmp_wa(type, extype), "type = %s, expected %s\n", wine_dbgstr_w(type), extype);
3208     else
3209         ok_(__FILE__,line)(!type, "type = %s, expected NULL\n", wine_dbgstr_w(type));
3210
3211     IHTMLStyleElement_Release(style);
3212     SysFreeString(type);
3213 }
3214
3215 #define test_style_put_type(s,m) _test_style_put_type(__LINE__,s,m)
3216 static void _test_style_put_type(unsigned line, IUnknown *unk, const char *type)
3217 {
3218     IHTMLStyleElement *style = _get_style_iface(line, unk);
3219     BSTR str;
3220     HRESULT hres;
3221
3222     str = a2bstr(type);
3223     hres = IHTMLStyleElement_put_type(style, str);
3224     ok_(__FILE__,line)(hres == S_OK, "put_type failed: %08x\n", hres);
3225     IHTMLStyleElement_Release(style);
3226     SysFreeString(str);
3227
3228     _test_style_type(line, unk, type);
3229 }
3230
3231 #define test_elem_filters(u) _test_elem_filters(__LINE__,u)
3232 static void _test_elem_filters(unsigned line, IUnknown *unk)
3233 {
3234     IHTMLElement *elem = _get_elem_iface(line, unk);
3235     HRESULT hres;
3236     IHTMLFiltersCollection *filters;
3237
3238     hres = IHTMLElement_get_filters(elem, &filters);
3239     ok_(__FILE__,line) (hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG) /* NT4 */,
3240                         "get_filters failed: %08x\n", hres);
3241     if(hres == S_OK)
3242     {
3243         LONG len;
3244         IDispatchEx *dispex;
3245
3246         hres = IHTMLFiltersCollection_get_length(filters, &len);
3247         ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
3248         ok_(__FILE__,line) (len == 0, "expect 0 got %d\n", len);
3249
3250         hres = IHTMLFiltersCollection_QueryInterface(filters, &IID_IDispatchEx, (void**)&dispex);
3251         ok_(__FILE__,line) (hres == S_OK || broken(hres == E_NOINTERFACE),
3252                             "Could not get IDispatchEx interface: %08x\n", hres);
3253         if(SUCCEEDED(hres)) {
3254             test_disp((IUnknown*)filters, &IID_IHTMLFiltersCollection, "[object]");
3255             IDispatchEx_Release(dispex);
3256         }
3257
3258         IHTMLFiltersCollection_Release(filters);
3259     }
3260
3261     IHTMLElement_Release(elem);
3262 }
3263
3264 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
3265 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
3266 {
3267     IHTMLElement *elem = _get_elem_iface(line, unk);
3268     BSTR tmp;
3269     HRESULT hres;
3270
3271     tmp = class ? a2bstr(class) : NULL;
3272     hres = IHTMLElement_put_className(elem, tmp);
3273     IHTMLElement_Release(elem);
3274     ok_(__FILE__,line) (hres == S_OK, "put_className failed: %08x\n", hres);
3275     SysFreeString(tmp);
3276
3277     _test_elem_class(line, unk, class);
3278 }
3279
3280 #define test_elem_id(e,i) _test_elem_id(__LINE__,e,i)
3281 static void _test_elem_id(unsigned line, IUnknown *unk, const char *exid)
3282 {
3283     IHTMLElement *elem = _get_elem_iface(line, unk);
3284     BSTR id = (void*)0xdeadbeef;
3285     HRESULT hres;
3286
3287     hres = IHTMLElement_get_id(elem, &id);
3288     IHTMLElement_Release(elem);
3289     ok_(__FILE__,line) (hres == S_OK, "get_id failed: %08x\n", hres);
3290
3291     if(exid)
3292         ok_(__FILE__,line) (!strcmp_wa(id, exid), "unexpected id %s\n", wine_dbgstr_w(id));
3293     else
3294         ok_(__FILE__,line) (!id, "id=%s\n", wine_dbgstr_w(id));
3295
3296     SysFreeString(id);
3297 }
3298
3299 #define test_elem_put_id(u,i) _test_elem_put_id(__LINE__,u,i)
3300 static void _test_elem_put_id(unsigned line, IUnknown *unk, const char *new_id)
3301 {
3302     IHTMLElement *elem = _get_elem_iface(line, unk);
3303     BSTR tmp = a2bstr(new_id);
3304     HRESULT hres;
3305
3306     hres = IHTMLElement_put_id(elem, tmp);
3307     IHTMLElement_Release(elem);
3308     SysFreeString(tmp);
3309     ok_(__FILE__,line) (hres == S_OK, "put_id failed: %08x\n", hres);
3310
3311     _test_elem_id(line, unk, new_id);
3312 }
3313
3314 #define test_elem_title(u,t) _test_elem_title(__LINE__,u,t)
3315 static void _test_elem_title(unsigned line, IUnknown *unk, const char *extitle)
3316 {
3317     IHTMLElement *elem = _get_elem_iface(line, unk);
3318     BSTR title;
3319     HRESULT hres;
3320
3321     hres = IHTMLElement_get_title(elem, &title);
3322     IHTMLElement_Release(elem);
3323     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3324     if(extitle)
3325         ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
3326     else
3327         ok_(__FILE__,line) (!title, "title=%s, expected NULL\n", wine_dbgstr_w(title));
3328
3329     SysFreeString(title);
3330 }
3331
3332 #define test_elem_set_title(u,t) _test_elem_set_title(__LINE__,u,t)
3333 static void _test_elem_set_title(unsigned line, IUnknown *unk, const char *title)
3334 {
3335     IHTMLElement *elem = _get_elem_iface(line, unk);
3336     BSTR tmp;
3337     HRESULT hres;
3338
3339     tmp = a2bstr(title);
3340     hres = IHTMLElement_put_title(elem, tmp);
3341     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3342
3343     IHTMLElement_Release(elem);
3344     SysFreeString(tmp);
3345 }
3346
3347 #define test_node_get_value_str(u,e) _test_node_get_value_str(__LINE__,u,e)
3348 static void _test_node_get_value_str(unsigned line, IUnknown *unk, const char *exval)
3349 {
3350     IHTMLDOMNode *node = _get_node_iface(line, unk);
3351     VARIANT var;
3352     HRESULT hres;
3353
3354     hres = IHTMLDOMNode_get_nodeValue(node, &var);
3355     IHTMLDOMNode_Release(node);
3356     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
3357
3358     if(exval) {
3359         ok_(__FILE__,line) (V_VT(&var) == VT_BSTR, "vt=%d\n", V_VT(&var));
3360         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&var), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&var)));
3361     }else {
3362         ok_(__FILE__,line) (V_VT(&var) == VT_NULL, "vt=%d, expected VT_NULL\n", V_VT(&var));
3363     }
3364
3365     VariantClear(&var);
3366 }
3367
3368 #define test_node_put_value_str(u,v) _test_node_put_value_str(__LINE__,u,v)
3369 static void _test_node_put_value_str(unsigned line, IUnknown *unk, const char *val)
3370 {
3371     IHTMLDOMNode *node = _get_node_iface(line, unk);
3372     VARIANT var;
3373     HRESULT hres;
3374
3375     V_VT(&var) = VT_BSTR;
3376     V_BSTR(&var) = a2bstr(val);
3377
3378     hres = IHTMLDOMNode_put_nodeValue(node, var);
3379     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
3380     IHTMLDOMNode_Release(node);
3381     VariantClear(&var);
3382 }
3383
3384 #define test_elem_client_size(u) _test_elem_client_size(__LINE__,u)
3385 static void _test_elem_client_size(unsigned line, IUnknown *unk)
3386 {
3387     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3388     LONG l;
3389     HRESULT hres;
3390
3391     hres = IHTMLElement2_get_clientWidth(elem, &l);
3392     ok_(__FILE__,line) (hres == S_OK, "get_clientWidth failed: %08x\n", hres);
3393     hres = IHTMLElement2_get_clientHeight(elem, &l);
3394     ok_(__FILE__,line) (hres == S_OK, "get_clientHeight failed: %08x\n", hres);
3395
3396     IHTMLElement2_Release(elem);
3397 }
3398
3399 #define test_elem_client_rect(u) _test_elem_client_rect(__LINE__,u)
3400 static void _test_elem_client_rect(unsigned line, IUnknown *unk)
3401 {
3402     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3403     LONG l;
3404     HRESULT hres;
3405
3406     hres = IHTMLElement2_get_clientLeft(elem, &l);
3407     ok_(__FILE__,line) (hres == S_OK, "get_clientLeft failed: %08x\n", hres);
3408     ok_(__FILE__,line) (!l, "clientLeft = %d\n", l);
3409
3410     hres = IHTMLElement2_get_clientTop(elem, &l);
3411     ok_(__FILE__,line) (hres == S_OK, "get_clientTop failed: %08x\n", hres);
3412     ok_(__FILE__,line) (!l, "clientTop = %d\n", l);
3413
3414     IHTMLElement2_Release(elem);
3415 }
3416
3417 #define test_form_length(e,l) _test_form_length(__LINE__,e,l)
3418 static void _test_form_length(unsigned line, IUnknown *unk, LONG exlen)
3419 {
3420     IHTMLFormElement *form = _get_form_iface(line, unk);
3421     LONG len = 0xdeadbeef;
3422     HRESULT hres;
3423
3424     hres = IHTMLFormElement_get_length(form, &len);
3425     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
3426     ok_(__FILE__,line)(len == exlen, "length=%d, expected %d\n", len, exlen);
3427
3428     IHTMLFormElement_Release(form);
3429 }
3430
3431 #define test_form_action(f,a) _test_form_action(__LINE__,f,a)
3432 static void _test_form_action(unsigned line, IUnknown *unk, const char *ex)
3433 {
3434     IHTMLFormElement *form = _get_form_iface(line, unk);
3435     BSTR action = (void*)0xdeadbeef;
3436     HRESULT hres;
3437
3438     hres = IHTMLFormElement_get_action(form, &action);
3439     ok_(__FILE__,line)(hres == S_OK, "get_action failed: %08x\n", hres);
3440     if(ex)
3441         ok_(__FILE__,line)(!strcmp_wa(action, ex), "action=%s, expected %s\n", wine_dbgstr_w(action), ex);
3442     else
3443         ok_(__FILE__,line)(!action, "action=%p\n", action);
3444
3445     SysFreeString(action);
3446     IHTMLFormElement_Release(form);
3447 }
3448
3449 #define test_form_put_action(f,a) _test_form_put_action(__LINE__,f,a)
3450 static void _test_form_put_action(unsigned line, IUnknown *unk, const char *action)
3451 {
3452     IHTMLFormElement *form = _get_form_iface(line, unk);
3453     BSTR tmp = a2bstr(action);
3454     HRESULT hres;
3455
3456     hres = IHTMLFormElement_put_action(form, tmp);
3457     ok_(__FILE__,line)(hres == S_OK, "put_action failed: %08x\n", hres);
3458     SysFreeString(tmp);
3459     IHTMLFormElement_Release(form);
3460
3461     _test_form_action(line, unk, action);
3462 }
3463
3464 #define test_form_method(f,a) _test_form_method(__LINE__,f,a)
3465 static void _test_form_method(unsigned line, IUnknown *unk, const char *ex)
3466 {
3467     IHTMLFormElement *form = _get_form_iface(line, unk);
3468     BSTR method = (void*)0xdeadbeef;
3469     HRESULT hres;
3470
3471     hres = IHTMLFormElement_get_method(form, &method);
3472     ok_(__FILE__,line)(hres == S_OK, "get_method failed: %08x\n", hres);
3473     if(ex)
3474         ok_(__FILE__,line)(!strcmp_wa(method, ex), "method=%s, expected %s\n", wine_dbgstr_w(method), ex);
3475     else
3476         ok_(__FILE__,line)(!method, "method=%p\n", method);
3477
3478     SysFreeString(method);
3479     IHTMLFormElement_Release(form);
3480 }
3481
3482 #define test_form_put_method(f,r,a) _test_form_put_method(__LINE__,f,r,a)
3483 static void _test_form_put_method(unsigned line, IUnknown *unk, HRESULT exp_hres, const char *method)
3484 {
3485     IHTMLFormElement *form = _get_form_iface(line, unk);
3486     BSTR tmp = a2bstr(method);
3487     HRESULT hres;
3488
3489     hres = IHTMLFormElement_put_method(form, tmp);
3490     ok_(__FILE__,line)(hres == exp_hres, "put_method returned: %08x, expected %08x\n", hres, exp_hres);
3491     SysFreeString(tmp);
3492     IHTMLFormElement_Release(form);
3493
3494     if(exp_hres == S_OK)
3495         _test_form_method(line, unk, method);
3496 }
3497
3498 #define test_form_name(f,a) _test_form_name(__LINE__,f,a)
3499 static void _test_form_name(unsigned line, IUnknown *unk, const char *ex)
3500 {
3501     IHTMLFormElement *form = _get_form_iface(line, unk);
3502     BSTR name = (void*)0xdeadbeef;
3503     HRESULT hres;
3504
3505     hres = IHTMLFormElement_get_name(form, &name);
3506     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
3507     if(ex)
3508         ok_(__FILE__,line)(!strcmp_wa(name, ex), "name=%s, expected %s\n", wine_dbgstr_w(name), ex);
3509     else
3510         ok_(__FILE__,line)(!name, "name=%p\n", name);
3511
3512     SysFreeString(name);
3513     IHTMLFormElement_Release(form);
3514 }
3515
3516 #define test_form_put_name(f,a) _test_form_put_name(__LINE__,f,a)
3517 static void _test_form_put_name(unsigned line, IUnknown *unk, const char *name)
3518 {
3519     IHTMLFormElement *form = _get_form_iface(line, unk);
3520     BSTR tmp = a2bstr(name);
3521     HRESULT hres;
3522
3523     hres = IHTMLFormElement_put_name(form, tmp);
3524     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
3525     SysFreeString(tmp);
3526     IHTMLFormElement_Release(form);
3527
3528     _test_form_name(line, unk, name);
3529 }
3530
3531 #define test_form_encoding(f,a) _test_form_encoding(__LINE__,f,a)
3532 static void _test_form_encoding(unsigned line, IUnknown *unk, const char *ex)
3533 {
3534     IHTMLFormElement *form = _get_form_iface(line, unk);
3535     BSTR encoding = (void*)0xdeadbeef;
3536     HRESULT hres;
3537
3538     hres = IHTMLFormElement_get_encoding(form, &encoding);
3539     ok_(__FILE__,line)(hres == S_OK, "get_encoding failed: %08x\n", hres);
3540     if(ex)
3541         ok_(__FILE__,line)(!strcmp_wa(encoding, ex), "encoding=%s, expected %s\n", wine_dbgstr_w(encoding), ex);
3542     else
3543         ok_(__FILE__,line)(!encoding, "encoding=%p\n", encoding);
3544
3545     SysFreeString(encoding);
3546     IHTMLFormElement_Release(form);
3547 }
3548
3549 #define test_form_put_encoding(f,r,a) _test_form_put_encoding(__LINE__,f,r,a)
3550 static void _test_form_put_encoding(unsigned line, IUnknown *unk, HRESULT exp_hres, const char *encoding)
3551 {
3552     IHTMLFormElement *form = _get_form_iface(line, unk);
3553     BSTR tmp = a2bstr(encoding);
3554     HRESULT hres;
3555
3556     hres = IHTMLFormElement_put_encoding(form, tmp);
3557     ok_(__FILE__,line)(hres == exp_hres, "put_encoding returned: %08x, expected %08x\n", hres, exp_hres);
3558     SysFreeString(tmp);
3559     IHTMLFormElement_Release(form);
3560
3561     if(exp_hres == S_OK)
3562         _test_form_encoding(line, unk, encoding);
3563 }
3564
3565 #define test_form_elements(a) _test_form_elements(__LINE__,a)
3566 static void _test_form_elements(unsigned line, IUnknown *unk)
3567 {
3568     IHTMLFormElement *form = _get_form_iface(line, unk);
3569     IDispatch *disp;
3570     HRESULT hres;
3571
3572     disp = NULL;
3573     hres = IHTMLFormElement_get_elements(form, &disp);
3574     ok_(__FILE__,line)(hres == S_OK, "get_elements failed: %08x\n", hres);
3575     ok_(__FILE__,line)(disp != NULL, "disp = NULL\n");
3576     ok_(__FILE__,line)(iface_cmp((IUnknown*)form, (IUnknown*)disp), "disp != form\n");
3577
3578     IDispatch_Release(disp);
3579     IHTMLFormElement_Release(form);
3580 }
3581
3582 #define test_meta_name(a,b) _test_meta_name(__LINE__,a,b)
3583 static void _test_meta_name(unsigned line, IUnknown *unk, const char *exname)
3584 {
3585     IHTMLMetaElement *meta;
3586     BSTR name = NULL;
3587     HRESULT hres;
3588
3589
3590     meta = _get_metaelem_iface(line, unk);
3591     hres = IHTMLMetaElement_get_name(meta, &name);
3592     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
3593     ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s, expected %s\n", wine_dbgstr_w(name), exname);
3594     SysFreeString(name);
3595     IHTMLMetaElement_Release(meta);
3596 }
3597
3598 #define test_meta_content(a,b) _test_meta_content(__LINE__,a,b)
3599 static void _test_meta_content(unsigned line, IUnknown *unk, const char *excontent)
3600 {
3601     IHTMLMetaElement *meta;
3602     BSTR content = NULL;
3603     HRESULT hres;
3604
3605
3606     meta = _get_metaelem_iface(line, unk);
3607     hres = IHTMLMetaElement_get_content(meta, &content);
3608     ok_(__FILE__,line)(hres == S_OK, "get_content failed: %08x\n", hres);
3609     ok_(__FILE__,line)(!strcmp_wa(content, excontent), "content = %s, expected %s\n", wine_dbgstr_w(content), excontent);
3610     SysFreeString(content);
3611     IHTMLMetaElement_Release(meta);
3612 }
3613
3614 #define test_meta_httpequiv(a,b) _test_meta_httpequiv(__LINE__,a,b)
3615 static void _test_meta_httpequiv(unsigned line, IUnknown *unk, const char *exval)
3616 {
3617     IHTMLMetaElement *meta;
3618     BSTR val = NULL;
3619     HRESULT hres;
3620
3621
3622     meta = _get_metaelem_iface(line, unk);
3623     hres = IHTMLMetaElement_get_httpEquiv(meta, &val);
3624     ok_(__FILE__,line)(hres == S_OK, "get_httpEquiv failed: %08x\n", hres);
3625     ok_(__FILE__,line)(!strcmp_wa(val, exval), "httpEquiv = %s, expected %s\n", wine_dbgstr_w(val), exval);
3626     SysFreeString(val);
3627     IHTMLMetaElement_Release(meta);
3628 }
3629
3630 #define test_link_disabled(a,b) _test_link_disabled(__LINE__,a,b)
3631 static void _test_link_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL v)
3632 {
3633     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3634     VARIANT_BOOL b = 10;
3635     HRESULT hres;
3636
3637     hres = IHTMLLinkElement_get_disabled(link, &b);
3638     ok_(__FILE__,line)(hres == S_OK, "get_disabled failed: %08x\n", hres);
3639     ok_(__FILE__,line)(b == v, "disabled = %x, expected %x\n", b, v);
3640
3641     IHTMLLinkElement_Release(link);
3642 }
3643
3644 #define link_put_disabled(a,b) _link_put_disabled(__LINE__,a,b)
3645 static void _link_put_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL v)
3646 {
3647     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3648     HRESULT hres;
3649
3650     hres = IHTMLLinkElement_put_disabled(link, v);
3651     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3652     IHTMLLinkElement_Release(link);
3653     _test_link_disabled(line, elem, v);
3654 }
3655
3656 #define test_link_rel(a,b) _test_link_rel(__LINE__,a,b)
3657 static void _test_link_rel(unsigned line, IHTMLElement *elem, const char *v)
3658 {
3659     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3660     BSTR rel;
3661     HRESULT hres;
3662
3663     hres = IHTMLLinkElement_get_rel(link, &rel);
3664     ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
3665     if(v)
3666         ok_(__FILE__,line)(!strcmp_wa(rel, v), "rel = %s, expected %s\n", wine_dbgstr_w(rel), v);
3667     else
3668         ok_(__FILE__,line)(!rel, "rel = %s, expected NULL\n", wine_dbgstr_w(rel));
3669
3670     IHTMLLinkElement_Release(link);
3671 }
3672
3673 #define link_put_rel(a,b) _link_put_rel(__LINE__,a,b)
3674 static void _link_put_rel(unsigned line, IHTMLElement *elem, const char *v)
3675 {
3676     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3677     BSTR str = a2bstr(v);
3678     HRESULT hres;
3679
3680     hres = IHTMLLinkElement_put_rel(link, str);
3681     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3682     SysFreeString(str);
3683     IHTMLLinkElement_Release(link);
3684     _test_link_rel(line, elem, v);
3685 }
3686
3687 #define test_link_type(a,b) _test_link_type(__LINE__,a,b)
3688 static void _test_link_type(unsigned line, IHTMLElement *elem, const char *v)
3689 {
3690     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3691     BSTR type;
3692     HRESULT hres;
3693
3694     hres = IHTMLLinkElement_get_type(link, &type);
3695     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
3696     if(v)
3697         ok_(__FILE__,line)(!strcmp_wa(type, v), "type = %s, expected %s\n", wine_dbgstr_w(type), v);
3698     else
3699         ok_(__FILE__,line)(!type, "type = %s, expected NULL\n", wine_dbgstr_w(type));
3700
3701     IHTMLLinkElement_Release(link);
3702 }
3703
3704 #define test_script_text(a,b) _test_script_text(__LINE__,a,b)
3705 static void _test_script_text(unsigned line, IHTMLScriptElement *script, const char *extext)
3706 {
3707     BSTR str;
3708     HRESULT hres;
3709
3710     str = (void*)0xdeadbeef;
3711     hres = IHTMLScriptElement_get_text(script, &str);
3712     ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
3713     ok(!strcmp_wa(str, extext), "text = %s, expected \"%s\"\n", wine_dbgstr_w(str), extext);
3714     SysFreeString(str);
3715 }
3716
3717 #define link_put_type(a,b) _link_put_type(__LINE__,a,b)
3718 static void _link_put_type(unsigned line, IHTMLElement *elem, const char *v)
3719 {
3720     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3721     BSTR str = a2bstr(v);
3722     HRESULT hres;
3723
3724     hres = IHTMLLinkElement_put_type(link, str);
3725     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3726     SysFreeString(str);
3727     IHTMLLinkElement_Release(link);
3728     _test_link_type(line, elem, v);
3729 }
3730
3731 #define test_link_href(a,b) _test_link_href(__LINE__,a,b)
3732 static void _test_link_href(unsigned line, IHTMLElement *elem, const char *v)
3733 {
3734     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3735     BSTR href;
3736     HRESULT hres;
3737
3738     hres = IHTMLLinkElement_get_href(link, &href);
3739     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
3740     if(v)
3741         ok_(__FILE__,line)(!strcmp_wa(href, v), "href = %s, expected %s\n", wine_dbgstr_w(href), v);
3742     else
3743         ok_(__FILE__,line)(!href, "href = %s, expected NULL\n", wine_dbgstr_w(href));
3744
3745     IHTMLLinkElement_Release(link);
3746 }
3747
3748 #define link_put_href(a,b) _link_put_href(__LINE__,a,b)
3749 static void _link_put_href(unsigned line, IHTMLElement *elem, const char *v)
3750 {
3751     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3752     BSTR str = a2bstr(v);
3753     HRESULT hres;
3754
3755     hres = IHTMLLinkElement_put_href(link, str);
3756     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3757     SysFreeString(str);
3758     IHTMLLinkElement_Release(link);
3759     _test_link_href(line, elem, v);
3760 }
3761
3762 #define get_elem_doc(e) _get_elem_doc(__LINE__,e)
3763 static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk)
3764 {
3765     IHTMLElement *elem = _get_elem_iface(line, unk);
3766     IHTMLDocument2 *doc;
3767     IDispatch *disp;
3768     HRESULT hres;
3769
3770     disp = NULL;
3771     hres = IHTMLElement_get_document(elem, &disp);
3772     ok(hres == S_OK, "get_document failed: %08x\n", hres);
3773     ok(disp != NULL, "disp == NULL\n");
3774
3775     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
3776     IDispatch_Release(disp);
3777     ok(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
3778
3779     return doc;
3780 }
3781
3782 #define get_elem_attr_node(a,b,c) _get_elem_attr_node(__LINE__,a,b,c)
3783 static IHTMLDOMAttribute *_get_elem_attr_node(unsigned line, IUnknown *unk, const char *attr_name, BOOL expect_success)
3784 {
3785     IHTMLElement4 *elem = _get_elem4_iface(line, unk);
3786     BSTR str = a2bstr(attr_name);
3787     IHTMLDOMAttribute *attr;
3788     HRESULT hres;
3789
3790     attr = (void*)0xdeadbeef;
3791     hres = IHTMLElement4_getAttributeNode(elem, str, &attr);
3792     ok_(__FILE__,line)(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
3793     if(expect_success)
3794         ok_(__FILE__,line)(attr != NULL, "attr = NULL\n");
3795     else
3796         ok_(__FILE__,line)(!attr, "attr = %p\n", attr);
3797
3798     IHTMLElement4_Release(elem);
3799     SysFreeString(str);
3800     return attr;
3801 }
3802
3803 #define get_attr_node_value(a,b,c) _get_attr_node_value(__LINE__,a,b,c)
3804 static void _get_attr_node_value(unsigned line, IHTMLDOMAttribute *attr, VARIANT *v, VARTYPE vt)
3805 {
3806     HRESULT hres;
3807
3808     hres = IHTMLDOMAttribute_get_nodeValue(attr, v);
3809     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
3810     ok_(__FILE__,line) (V_VT(v) == vt, "vt=%d, expected %d\n", V_VT(v), vt);
3811 }
3812
3813 #define get_window_doc(e) _get_window_doc(__LINE__,e)
3814 static IHTMLDocument2 *_get_window_doc(unsigned line, IHTMLWindow2 *window)
3815 {
3816     IHTMLDocument2 *doc;
3817     HRESULT hres;
3818
3819     doc = NULL;
3820     hres = IHTMLWindow2_get_document(window, &doc);
3821     ok(hres == S_OK, "get_document failed: %08x\n", hres);
3822     ok(doc != NULL, "disp == NULL\n");
3823
3824     return doc;
3825 }
3826
3827 #define doc_get_body(d) _doc_get_body(__LINE__,d)
3828 static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc)
3829 {
3830     IHTMLElement *elem;
3831     HRESULT hres;
3832
3833     hres = IHTMLDocument2_get_body(doc, &elem);
3834     ok_(__FILE__,line)(hres == S_OK, "get_body failed: %08x\n", hres);
3835     ok_(__FILE__,line)(elem != NULL, "body == NULL\n");
3836
3837     return elem;
3838 }
3839
3840 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
3841 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
3842 {
3843     IHTMLElement *elem = NULL;
3844     BSTR tmp;
3845     HRESULT hres;
3846
3847     tmp = a2bstr(tag);
3848     hres = IHTMLDocument2_createElement(doc, tmp, &elem);
3849     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
3850     ok_(__FILE__,line) (elem != NULL, "elem == NULL\n");
3851     SysFreeString(tmp);
3852
3853     return elem;
3854 }
3855
3856 #define test_create_text(d,t) _test_create_text(__LINE__,d,t)
3857 static IHTMLDOMNode *_test_create_text(unsigned line, IHTMLDocument2 *doc, const char *text)
3858 {
3859     IHTMLDocument3 *doc3;
3860     IHTMLDOMNode *node = NULL;
3861     BSTR tmp;
3862     HRESULT hres;
3863
3864     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
3865     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3: %08x\n", hres);
3866
3867     tmp = a2bstr(text);
3868     hres = IHTMLDocument3_createTextNode(doc3, tmp, &node);
3869     IHTMLDocument3_Release(doc3);
3870     SysFreeString(tmp);
3871     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
3872     ok_(__FILE__,line) (node != NULL, "node == NULL\n");
3873
3874     return node;
3875 }
3876
3877 #define test_node_append_child(n,c) _test_node_append_child(__LINE__,n,c)
3878 static IHTMLDOMNode *_test_node_append_child(unsigned line, IUnknown *node_unk, IUnknown *child_unk)
3879 {
3880     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
3881     IHTMLDOMNode *child = _get_node_iface(line, child_unk);
3882     IHTMLDOMNode *new_child = NULL;
3883     HRESULT hres;
3884
3885     hres = IHTMLDOMNode_appendChild(node, child, &new_child);
3886     ok_(__FILE__,line) (hres == S_OK, "appendChild failed: %08x\n", hres);
3887     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
3888     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
3889
3890     IHTMLDOMNode_Release(node);
3891     IHTMLDOMNode_Release(child);
3892
3893     return new_child;
3894 }
3895
3896 #define test_node_insertbefore(n,c,v) _test_node_insertbefore(__LINE__,n,c,v)
3897 static IHTMLDOMNode *_test_node_insertbefore(unsigned line, IUnknown *node_unk, IHTMLDOMNode *child, VARIANT *var)
3898 {
3899     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
3900     IHTMLDOMNode *new_child = NULL;
3901     HRESULT hres;
3902
3903     hres = IHTMLDOMNode_insertBefore(node, child, *var, &new_child);
3904     ok_(__FILE__,line) (hres == S_OK, "insertBefore failed: %08x\n", hres);
3905     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
3906     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
3907
3908     IHTMLDOMNode_Release(node);
3909
3910     return new_child;
3911 }
3912
3913 #define test_node_remove_child(n,c) _test_node_remove_child(__LINE__,n,c)
3914 static void _test_node_remove_child(unsigned line, IUnknown *unk, IHTMLDOMNode *child)
3915 {
3916     IHTMLDOMNode *node = _get_node_iface(line, unk);
3917     IHTMLDOMNode *new_node = NULL;
3918     HRESULT hres;
3919
3920     hres = IHTMLDOMNode_removeChild(node, child, &new_node);
3921     ok_(__FILE__,line) (hres == S_OK, "removeChild failed: %08x\n", hres);
3922     ok_(__FILE__,line) (new_node != NULL, "new_node == NULL\n");
3923     /* TODO ok_(__FILE__,line) (new_node != child, "new_node == child\n"); */
3924
3925     IHTMLDOMNode_Release(node);
3926     IHTMLDOMNode_Release(new_node);
3927 }
3928
3929 #define test_doc_title(d,t) _test_doc_title(__LINE__,d,t)
3930 static void _test_doc_title(unsigned line, IHTMLDocument2 *doc, const char *extitle)
3931 {
3932     BSTR title = NULL;
3933     HRESULT hres;
3934
3935     hres = IHTMLDocument2_get_title(doc, &title);
3936     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3937     ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
3938     SysFreeString(title);
3939 }
3940
3941 #define test_doc_set_title(d,t) _test_doc_set_title(__LINE__,d,t)
3942 static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *title)
3943 {
3944     BSTR tmp;
3945     HRESULT hres;
3946
3947     tmp = a2bstr(title);
3948     hres = IHTMLDocument2_put_title(doc, tmp);
3949     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3950     SysFreeString(tmp);
3951 }
3952
3953 static void test_elem_bounding_client_rect(IUnknown *unk)
3954 {
3955     IHTMLRect *rect, *rect2;
3956     IHTMLElement2 *elem2;
3957     LONG l;
3958     HRESULT hres;
3959
3960     elem2 = get_elem2_iface(unk);
3961     hres = IHTMLElement2_getBoundingClientRect(elem2, &rect);
3962     ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres);
3963     hres = IHTMLElement2_getBoundingClientRect(elem2, &rect2);
3964     IHTMLElement2_Release(elem2);
3965     ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres);
3966     ok(rect != NULL, "rect == NULL\n");
3967     ok(rect != rect2, "rect == rect2\n");
3968     IHTMLRect_Release(rect2);
3969
3970     test_disp((IUnknown*)rect, &IID_IHTMLRect, "[object]");
3971
3972     l = 0xdeadbeef;
3973     hres = IHTMLRect_get_top(rect, &l);
3974     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3975     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3976
3977     l = 0xdeadbeef;
3978     hres = IHTMLRect_get_left(rect, &l);
3979     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3980     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3981
3982     l = 0xdeadbeef;
3983     hres = IHTMLRect_get_bottom(rect, &l);
3984     ok(hres == S_OK, "get_bottom failed: %08x\n", hres);
3985     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3986
3987     l = 0xdeadbeef;
3988     hres = IHTMLRect_get_right(rect, &l);
3989     ok(hres == S_OK, "get_right failed: %08x\n", hres);
3990     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3991
3992     IHTMLRect_Release(rect);
3993 }
3994
3995 static void test_elem_col_item(IHTMLElementCollection *col, const char *n,
3996         const elem_type_t *elem_types, LONG len)
3997 {
3998     IDispatch *disp;
3999     VARIANT name, index;
4000     DWORD i;
4001     HRESULT hres;
4002
4003     V_VT(&index) = VT_EMPTY;
4004     V_VT(&name) = VT_BSTR;
4005     V_BSTR(&name) = a2bstr(n);
4006
4007     hres = IHTMLElementCollection_item(col, name, index, &disp);
4008     ok(hres == S_OK, "item failed: %08x\n", hres);
4009
4010     test_elem_collection((IUnknown*)disp, elem_types, len);
4011     IDispatch_Release(disp);
4012
4013     V_VT(&index) = VT_I4;
4014
4015     for(i=0; i<len; i++) {
4016         V_I4(&index) = i;
4017         disp = (void*)0xdeadbeef;
4018         hres = IHTMLElementCollection_item(col, name, index, &disp);
4019         ok(hres == S_OK, "item failed: %08x\n", hres);
4020         ok(disp != NULL, "disp == NULL\n");
4021         if(FAILED(hres) || !disp)
4022             continue;
4023
4024         test_elem_type((IUnknown*)disp, elem_types[i]);
4025
4026         IDispatch_Release(disp);
4027     }
4028
4029     V_I4(&index) = len;
4030     disp = (void*)0xdeadbeef;
4031     hres = IHTMLElementCollection_item(col, name, index, &disp);
4032     ok(hres == S_OK, "item failed: %08x\n", hres);
4033     ok(disp == NULL, "disp != NULL\n");
4034
4035     V_I4(&index) = -1;
4036     disp = (void*)0xdeadbeef;
4037     hres = IHTMLElementCollection_item(col, name, index, &disp);
4038     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4039     ok(disp == NULL, "disp != NULL\n");
4040
4041     SysFreeString(V_BSTR(&name));
4042 }
4043
4044 static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const char *id, BOOL expect_success)
4045 {
4046     IHTMLElementCollection *col;
4047     IHTMLElement *elem;
4048     IDispatch *disp = (void*)0xdeadbeef;
4049     VARIANT name, index;
4050     HRESULT hres;
4051
4052     hres = IHTMLDocument2_get_all(doc, &col);
4053     ok(hres == S_OK, "get_all failed: %08x\n", hres);
4054     ok(col != NULL, "col == NULL\n");
4055     if(FAILED(hres) || !col)
4056         return NULL;
4057
4058     V_VT(&index) = VT_EMPTY;
4059     V_VT(&name) = VT_BSTR;
4060     V_BSTR(&name) = a2bstr(id);
4061
4062     hres = IHTMLElementCollection_item(col, name, index, &disp);
4063     IHTMLElementCollection_Release(col);
4064     SysFreeString(V_BSTR(&name));
4065     ok(hres == S_OK, "item failed: %08x\n", hres);
4066     if(!expect_success) {
4067         ok(disp == NULL, "disp != NULL\n");
4068         return NULL;
4069     }
4070
4071     ok(disp != NULL, "disp == NULL\n");
4072     if(!disp)
4073         return NULL;
4074
4075     elem = get_elem_iface((IUnknown*)disp);
4076     IDispatch_Release(disp);
4077
4078     return elem;
4079 }
4080
4081 static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const char *id)
4082 {
4083     IHTMLDocument3 *doc3;
4084     IHTMLElement *elem;
4085     BSTR tmp;
4086     HRESULT hres;
4087
4088     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4089     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
4090
4091     tmp = a2bstr(id);
4092     hres = IHTMLDocument3_getElementById(doc3, tmp, &elem);
4093     SysFreeString(tmp);
4094     ok(hres == S_OK, "getElementById(%s) failed: %08x\n", id, hres);
4095
4096     IHTMLDocument3_Release(doc3);
4097
4098     return elem;
4099 }
4100
4101 static void test_select_elem(IHTMLSelectElement *select)
4102 {
4103     IDispatch *disp, *disp2;
4104     VARIANT name, index;
4105     HRESULT hres;
4106
4107     test_select_type(select, "select-one");
4108     test_select_length(select, 2);
4109     test_select_selidx(select, 0);
4110     test_select_put_selidx(select, 1);
4111
4112     test_select_set_value(select, "val1");
4113     test_select_value(select, "val1");
4114
4115     test_select_get_disabled(select, VARIANT_FALSE);
4116     test_select_set_disabled(select, VARIANT_TRUE);
4117     test_select_set_disabled(select, VARIANT_FALSE);
4118
4119     disp = NULL;
4120     hres = IHTMLSelectElement_get_options(select, &disp);
4121     ok(hres == S_OK, "get_options failed: %08x\n", hres);
4122     ok(disp != NULL, "options == NULL\n");
4123     ok(iface_cmp((IUnknown*)disp, (IUnknown*)select), "disp != select\n");
4124     IDispatch_Release(disp);
4125
4126     V_VT(&index) = VT_EMPTY;
4127     V_VT(&name) = VT_I4;
4128     V_I4(&name) = -1;
4129     disp = (void*)0xdeadbeef;
4130     hres = IHTMLSelectElement_item(select, name, index, &disp);
4131     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4132     ok(!disp, "disp = %p\n", disp);
4133
4134     V_I4(&name) = 2;
4135     disp = (void*)0xdeadbeef;
4136     hres = IHTMLSelectElement_item(select, name, index, &disp);
4137     ok(hres == S_OK, "item failed: %08x\n", hres);
4138     ok(!disp, "disp = %p\n", disp);
4139
4140     V_I4(&name) = 1;
4141     hres = IHTMLSelectElement_item(select, name, index, NULL);
4142     ok(hres == E_POINTER || broken(hres == E_INVALIDARG), "item failed: %08x, expected E_POINTER\n", hres);
4143
4144     disp = NULL;
4145     hres = IHTMLSelectElement_item(select, name, index, &disp);
4146     ok(hres == S_OK, "item failed: %08x\n", hres);
4147     ok(disp != NULL, "disp = NULL\n");
4148     test_disp((IUnknown*)disp, &DIID_DispHTMLOptionElement, NULL);
4149
4150     V_VT(&index) = VT_I4;
4151     V_I4(&index) = 1;
4152     disp2 = NULL;
4153     hres = IHTMLSelectElement_item(select, name, index, &disp2);
4154     ok(hres == S_OK, "item failed: %08x\n", hres);
4155     ok(disp2 != NULL, "disp = NULL\n");
4156     ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
4157     IDispatch_Release(disp2);
4158     IDispatch_Release(disp);
4159 }
4160
4161 static void test_form_item(IHTMLElement *elem)
4162 {
4163     IHTMLFormElement *form = get_form_iface((IUnknown*)elem);
4164     IDispatch *disp, *disp2;
4165     VARIANT name, index;
4166     HRESULT hres;
4167
4168     V_VT(&index) = VT_EMPTY;
4169     V_VT(&name) = VT_I4;
4170     V_I4(&name) = -1;
4171     disp = (void*)0xdeadbeef;
4172     hres = IHTMLFormElement_item(form, name, index, &disp);
4173     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4174     ok(!disp, "disp = %p\n", disp);
4175
4176     V_I4(&name) = 2;
4177     disp = (void*)0xdeadbeef;
4178     hres = IHTMLFormElement_item(form, name, index, &disp);
4179     ok(hres == S_OK, "item failed: %08x\n", hres);
4180     ok(!disp, "disp = %p\n", disp);
4181
4182     V_I4(&name) = 1;
4183     hres = IHTMLFormElement_item(form, name, index, NULL);
4184     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4185
4186     disp = NULL;
4187     hres = IHTMLFormElement_item(form, name, index, &disp);
4188     ok(hres == S_OK, "item failed: %08x\n", hres);
4189     ok(disp != NULL, "disp = NULL\n");
4190     test_disp((IUnknown*)disp, &DIID_DispHTMLInputElement, NULL);
4191
4192     V_VT(&index) = VT_I4;
4193     V_I4(&index) = 1;
4194     disp2 = NULL;
4195     hres = IHTMLFormElement_item(form, name, index, &disp2);
4196     ok(hres == S_OK, "item failed: %08x\n", hres);
4197     ok(disp2 != NULL, "disp = NULL\n");
4198     ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
4199     IDispatch_Release(disp2);
4200     IDispatch_Release(disp);
4201 }
4202
4203 static void test_create_option_elem(IHTMLDocument2 *doc)
4204 {
4205     IHTMLOptionElement *option;
4206
4207     option = create_option_elem(doc, "test text", "test value");
4208
4209     test_option_put_text(option, "new text");
4210     test_option_put_value(option, "new value");
4211     test_option_put_selected(option, VARIANT_TRUE);
4212     test_option_put_selected(option, VARIANT_FALSE);
4213
4214     IHTMLOptionElement_Release(option);
4215 }
4216
4217 static void test_create_img_elem(IHTMLDocument2 *doc)
4218 {
4219     IHTMLImgElement *img;
4220
4221     img = create_img_elem(doc, 10, 15);
4222
4223     if(img){
4224         test_img_put_width(img, 5);
4225         test_img_put_height(img, 20);
4226
4227         IHTMLImgElement_Release(img);
4228         img = NULL;
4229     }
4230
4231     img = create_img_elem(doc, -1, -1);
4232
4233     if(img){
4234         test_img_put_width(img, 5);
4235         test_img_put_height(img, 20);
4236
4237         IHTMLImgElement_Release(img);
4238     }
4239 }
4240
4241 #define insert_adjacent_elem(a,b,c) _insert_adjacent_elem(__LINE__,a,b,c)
4242 static void _insert_adjacent_elem(unsigned line, IHTMLElement *parent, const char *where, IHTMLElement *elem)
4243 {
4244     IHTMLElement2 *elem2 = _get_elem2_iface(line, (IUnknown*)parent);
4245     IHTMLElement *ret_elem = NULL;
4246     BSTR str = a2bstr(where);
4247     HRESULT hres;
4248
4249     hres = IHTMLElement2_insertAdjacentElement(elem2, str, elem, &ret_elem);
4250     IHTMLElement2_Release(elem2);
4251     SysFreeString(str);
4252     ok_(__FILE__,line)(hres == S_OK, "insertAdjacentElement failed: %08x\n", hres);
4253     ok_(__FILE__,line)(ret_elem == elem, "ret_elem != elem\n");
4254     IHTMLElement_Release(ret_elem);
4255 }
4256
4257 static void test_insert_adjacent_elems(IHTMLDocument2 *doc, IHTMLElement *parent)
4258 {
4259     IHTMLElement *elem, *elem2;
4260
4261     static const elem_type_t br_br[] = {ET_BR, ET_BR};
4262     static const elem_type_t br_div_br[] = {ET_BR, ET_DIV, ET_BR};
4263
4264     elem = test_create_elem(doc, "BR");
4265     insert_adjacent_elem(parent, "BeforeEnd", elem);
4266     IHTMLElement_Release(elem);
4267
4268     test_elem_all((IUnknown*)parent, br_br, 1);
4269
4270     elem = test_create_elem(doc, "BR");
4271     insert_adjacent_elem(parent, "beforeend", elem);
4272
4273     test_elem_all((IUnknown*)parent, br_br, 2);
4274
4275     elem2 = test_create_elem(doc, "DIV");
4276     insert_adjacent_elem(elem, "beforebegin", elem2);
4277     IHTMLElement_Release(elem2);
4278     IHTMLElement_Release(elem);
4279
4280     test_elem_all((IUnknown*)parent, br_div_br, 3);
4281 }
4282
4283 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
4284 {
4285     IHTMLBodyElement *body;
4286     IHTMLTxtRange *range;
4287     IHTMLElement *elem;
4288     HRESULT hres;
4289
4290     elem = doc_get_body(doc);
4291     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
4292     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
4293     IHTMLElement_Release(elem);
4294
4295     hres = IHTMLBodyElement_createTextRange(body, &range);
4296     IHTMLBodyElement_Release(body);
4297     ok(hres == S_OK, "createTextRange failed: %08x\n", hres);
4298
4299     return range;
4300 }
4301
4302 static void test_txtrange(IHTMLDocument2 *doc)
4303 {
4304     IHTMLTxtRange *body_range, *range, *range2;
4305     IHTMLSelectionObject *selection;
4306     IDispatch *disp_range;
4307     HRESULT hres;
4308
4309     body_range = test_create_body_range(doc);
4310
4311     test_range_text(body_range, "test abc 123\r\nit's text");
4312
4313     hres = IHTMLTxtRange_duplicate(body_range, &range);
4314     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4315
4316     hres = IHTMLTxtRange_duplicate(body_range, &range2);
4317     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4318     test_range_isequal(range, range2, VARIANT_TRUE);
4319
4320     test_range_text(range, "test abc 123\r\nit's text");
4321     test_range_text(body_range, "test abc 123\r\nit's text");
4322
4323     test_range_collapse(range, TRUE);
4324     test_range_isequal(range, range2, VARIANT_FALSE);
4325     test_range_inrange(range, range2, VARIANT_FALSE);
4326     test_range_inrange(range2, range, VARIANT_TRUE);
4327     IHTMLTxtRange_Release(range2);
4328
4329     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
4330     test_range_expand(range, wordW, VARIANT_FALSE, "test ");
4331     test_range_move(range, characterW, 2, 2);
4332     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
4333
4334     test_range_collapse(range, FALSE);
4335     test_range_expand(range, wordW, VARIANT_TRUE, "abc ");
4336
4337     test_range_collapse(range, FALSE);
4338     test_range_expand(range, wordW, VARIANT_TRUE, "123");
4339     test_range_expand(range, wordW, VARIANT_FALSE, "123");
4340     test_range_move(range, characterW, 2, 2);
4341     test_range_expand(range, wordW, VARIANT_TRUE, "123");
4342     test_range_moveend(range, characterW, -5, -5);
4343     test_range_text(range, NULL);
4344     test_range_moveend(range, characterW, 3, 3);
4345     test_range_text(range, "c 1");
4346     test_range_expand(range, texteditW, VARIANT_TRUE, "test abc 123\r\nit's text");
4347     test_range_collapse(range, TRUE);
4348     test_range_move(range, characterW, 4, 4);
4349     test_range_moveend(range, characterW, 1, 1);
4350     test_range_text(range, " ");
4351     test_range_move(range, wordW, 1, 1);
4352     test_range_moveend(range, characterW, 2, 2);
4353     test_range_text(range, "ab");
4354
4355     IHTMLTxtRange_Release(range);
4356
4357     hres = IHTMLTxtRange_duplicate(body_range, &range);
4358     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4359
4360     test_range_text(range, "test abc 123\r\nit's text");
4361     test_range_move(range, characterW, 3, 3);
4362     test_range_moveend(range, characterW, 1, 1);
4363     test_range_text(range, "t");
4364     test_range_moveend(range, characterW, 3, 3);
4365     test_range_text(range, "t ab");
4366     test_range_moveend(range, characterW, -2, -2);
4367     test_range_text(range, "t ");
4368     test_range_move(range, characterW, 6, 6);
4369     test_range_moveend(range, characterW, 3, 3);
4370     test_range_text(range, "123");
4371     test_range_moveend(range, characterW, 2, 2);
4372     test_range_text(range, "123\r\ni");
4373
4374     IHTMLTxtRange_Release(range);
4375
4376     hres = IHTMLTxtRange_duplicate(body_range, &range);
4377     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4378
4379     test_range_move(range, wordW, 1, 1);
4380     test_range_moveend(range, characterW, 2, 2);
4381     test_range_text(range, "ab");
4382
4383     test_range_move(range, characterW, -2, -2);
4384     test_range_moveend(range, characterW, 2, 2);
4385     test_range_text(range, "t ");
4386
4387     test_range_move(range, wordW, 3, 3);
4388     test_range_move(range, wordW, -2, -2);
4389     test_range_moveend(range, characterW, 2, 2);
4390     test_range_text(range, "ab");
4391
4392     test_range_move(range, characterW, -6, -5);
4393     test_range_moveend(range, characterW, -1, 0);
4394     test_range_moveend(range, characterW, -6, 0);
4395     test_range_move(range, characterW, 2, 2);
4396     test_range_moveend(range, characterW, 2, 2);
4397     test_range_text(range, "st");
4398     test_range_moveend(range, characterW, -6, -4);
4399     test_range_moveend(range, characterW, 2, 2);
4400
4401     IHTMLTxtRange_Release(range);
4402
4403     hres = IHTMLTxtRange_duplicate(body_range, &range);
4404     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4405
4406     test_range_move(range, wordW, 2, 2);
4407     test_range_moveend(range, characterW, 2, 2);
4408     test_range_text(range, "12");
4409
4410     test_range_move(range, characterW, 15, 14);
4411     test_range_move(range, characterW, -2, -2);
4412     test_range_moveend(range, characterW, 3, 2);
4413     test_range_text(range, "t");
4414     test_range_moveend(range, characterW, -1, -1);
4415     test_range_text(range, "t");
4416     test_range_expand(range, wordW, VARIANT_TRUE, "text");
4417     test_range_move(range, characterW, -2, -2);
4418     test_range_moveend(range, characterW, 2, 2);
4419     test_range_text(range, "s ");
4420     test_range_move(range, characterW, 100, 7);
4421     test_range_move(range, wordW, 1, 0);
4422     test_range_move(range, characterW, -2, -2);
4423     test_range_moveend(range, characterW, 3, 2);
4424     test_range_text(range, "t");
4425
4426     IHTMLTxtRange_Release(range);
4427
4428     hres = IHTMLTxtRange_duplicate(body_range, &range);
4429     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4430
4431     test_range_collapse(range, TRUE);
4432     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
4433     test_range_put_text(range, "word");
4434     test_range_text(body_range, "wordabc 123\r\nit's text");
4435     test_range_text(range, NULL);
4436     test_range_moveend(range, characterW, 3, 3);
4437     test_range_text(range, "abc");
4438     test_range_movestart(range, characterW, -2, -2);
4439     test_range_text(range, "rdabc");
4440     test_range_movestart(range, characterW, 3, 3);
4441     test_range_text(range, "bc");
4442     test_range_movestart(range, characterW, 4, 4);
4443     test_range_text(range, NULL);
4444     test_range_movestart(range, characterW, -3, -3);
4445     test_range_text(range, "c 1");
4446     test_range_movestart(range, characterW, -7, -6);
4447     test_range_text(range, "wordabc 1");
4448     test_range_movestart(range, characterW, 100, 22);
4449     test_range_text(range, NULL);
4450
4451     IHTMLTxtRange_Release(range);
4452     IHTMLTxtRange_Release(body_range);
4453
4454     hres = IHTMLDocument2_get_selection(doc, &selection);
4455     ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres);
4456
4457     hres = IHTMLSelectionObject_createRange(selection, &disp_range);
4458     ok(hres == S_OK, "IHTMLSelectionObject_createRange failed: %08x\n", hres);
4459     IHTMLSelectionObject_Release(selection);
4460
4461     hres = IDispatch_QueryInterface(disp_range, &IID_IHTMLTxtRange, (void **)&range);
4462     ok(hres == S_OK, "Could not get IID_IHTMLTxtRange interface: 0x%08x\n", hres);
4463     IDispatch_Release(disp_range);
4464
4465     test_range_text(range, NULL);
4466     test_range_moveend(range, characterW, 3, 3);
4467     test_range_text(range, "wor");
4468     test_range_parent(range, ET_BODY);
4469     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
4470     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
4471     test_range_move(range, characterW, 3, 3);
4472     test_range_expand(range, wordW, VARIANT_TRUE, "wordabc ");
4473     test_range_moveend(range, characterW, -4, -4);
4474     test_range_put_text(range, "abc def ");
4475     test_range_expand(range, texteditW, VARIANT_TRUE, "abc def abc 123\r\nit's text");
4476     test_range_move(range, wordW, 1, 1);
4477     test_range_movestart(range, characterW, -1, -1);
4478     test_range_text(range, " ");
4479     test_range_move(range, wordW, 1, 1);
4480     test_range_moveend(range, characterW, 3, 3);
4481     test_range_text(range, "def");
4482     test_range_put_text(range, "xyz");
4483     test_range_moveend(range, characterW, 1, 1);
4484     test_range_move(range, wordW, 1, 1);
4485     test_range_moveend(range, characterW, 2, 2);
4486     test_range_text(range, "ab");
4487
4488     IHTMLTxtRange_Release(range);
4489 }
4490
4491 static void test_txtrange2(IHTMLDocument2 *doc)
4492 {
4493     IHTMLTxtRange *range;
4494
4495     range = test_create_body_range(doc);
4496
4497     test_range_text(range, "abc\r\n\r\n123\r\n\r\n\r\ndef");
4498     test_range_move(range, characterW, 5, 5);
4499     test_range_moveend(range, characterW, 1, 1);
4500     test_range_text(range, "2");
4501     test_range_move(range, characterW, -3, -3);
4502     test_range_moveend(range, characterW, 3, 3);
4503     test_range_text(range, "c\r\n\r\n1");
4504     test_range_collapse(range, VARIANT_FALSE);
4505     test_range_moveend(range, characterW, 4, 4);
4506     test_range_text(range, "23");
4507     test_range_moveend(range, characterW, 1, 1);
4508     test_range_text(range, "23\r\n\r\n\r\nd");
4509     test_range_moveend(range, characterW, -1, -1);
4510     test_range_text(range, "23");
4511     test_range_moveend(range, characterW, -1, -1);
4512     test_range_text(range, "23");
4513     test_range_moveend(range, characterW, -2, -2);
4514     test_range_text(range, "2");
4515
4516     IHTMLTxtRange_Release(range);
4517 }
4518
4519 #define test_compatmode(a,b) _test_compatmode(__LINE__,a,b)
4520 static void _test_compatmode(unsigned  line, IHTMLDocument2 *doc2, const char *excompat)
4521 {
4522     IHTMLDocument5 *doc = get_htmldoc5_iface((IUnknown*)doc2);
4523     BSTR str;
4524     HRESULT hres;
4525
4526     hres = IHTMLDocument5_get_compatMode(doc, &str);
4527     ok_(__FILE__,line)(hres == S_OK, "get_compatMode failed: %08x\n", hres);
4528     ok_(__FILE__,line)(!strcmp_wa(str, excompat), "compatMode = %s, expected %s\n", wine_dbgstr_w(str), excompat);
4529
4530     IHTMLDocument5_Release(doc);
4531 }
4532
4533 static void test_location(IHTMLDocument2 *doc)
4534 {
4535     IHTMLLocation *location, *location2;
4536     IHTMLWindow2 *window;
4537     BSTR str;
4538     ULONG ref;
4539     HRESULT hres;
4540
4541     hres = IHTMLDocument2_get_location(doc, &location);
4542     ok(hres == S_OK, "get_location failed: %08x\n", hres);
4543
4544     hres = IHTMLDocument2_get_location(doc, &location2);
4545     ok(hres == S_OK, "get_location failed: %08x\n", hres);
4546
4547     ok(location == location2, "location != location2\n");
4548     IHTMLLocation_Release(location2);
4549
4550     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4551     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
4552
4553     hres = IHTMLWindow2_get_location(window, &location2);
4554     ok(hres == S_OK, "get_location failed: %08x\n", hres);
4555     ok(location == location2, "location != location2\n");
4556     IHTMLLocation_Release(location2);
4557
4558     test_ifaces((IUnknown*)location, location_iids);
4559     test_disp2((IUnknown*)location, &DIID_DispHTMLLocation, &IID_IHTMLLocation, "about:blank");
4560
4561     hres = IHTMLLocation_get_pathname(location, &str);
4562     ok(hres == S_OK, "get_pathname failed: %08x\n", hres);
4563     ok(!strcmp_wa(str, "blank"), "unexpected pathname %s\n", wine_dbgstr_w(str));
4564     SysFreeString(str);
4565
4566     hres = IHTMLLocation_get_href(location, NULL);
4567     ok(hres == E_POINTER, "get_href passed: %08x\n", hres);
4568
4569     hres = IHTMLLocation_get_href(location, &str);
4570     ok(hres == S_OK, "get_href failed: %08x\n", hres);
4571     ok(!strcmp_wa(str, "about:blank"), "unexpected href %s\n", wine_dbgstr_w(str));
4572     SysFreeString(str);
4573
4574     ref = IHTMLLocation_Release(location);
4575     ok(!ref, "location chould be destroyed here\n");
4576 }
4577
4578 static void test_plugins_col(IHTMLDocument2 *doc)
4579 {
4580     IHTMLPluginsCollection *col, *col2;
4581     IHTMLWindow2 *window;
4582     IOmNavigator *nav;
4583     ULONG ref;
4584     LONG len;
4585     HRESULT hres;
4586
4587     window = get_doc_window(doc);
4588     hres = IHTMLWindow2_get_navigator(window, &nav);
4589     IHTMLWindow2_Release(window);
4590
4591     hres = IOmNavigator_get_plugins(nav, &col);
4592     ok(hres == S_OK, "get_plugins failed: %08x\n", hres);
4593
4594     hres = IOmNavigator_get_plugins(nav, &col2);
4595     ok(hres == S_OK, "get_plugins failed: %08x\n", hres);
4596     ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n");
4597     IHTMLPluginsCollection_Release(col2);
4598
4599     test_disp2((IUnknown*)col, &DIID_DispCPlugins, &IID_IHTMLPluginsCollection, "[object]");
4600
4601     len = 0xdeadbeef;
4602     hres = IHTMLPluginsCollection_get_length(col, &len);
4603     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4604     ok(!len, "length = %d\n", len);
4605
4606     ref = IHTMLPluginsCollection_Release(col);
4607     ok(!ref, "ref=%d\n", ref);
4608
4609     IOmNavigator_Release(nav);
4610 }
4611
4612 static void test_mime_types_col(IOmNavigator *nav)
4613 {
4614     IHTMLMimeTypesCollection *col, *col2;
4615     LONG length;
4616     ULONG ref;
4617     HRESULT hres;
4618
4619     hres = IOmNavigator_get_mimeTypes(nav, &col);
4620     ok(hres == S_OK, "get_mimeTypes failed: %08x\n", hres);
4621
4622     hres = IOmNavigator_get_mimeTypes(nav, &col2);
4623     ok(hres == S_OK, "get_mimeTypes failed: %08x\n", hres);
4624     ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n");
4625     IHTMLMimeTypesCollection_Release(col2);
4626
4627     test_disp((IUnknown*)col, &IID_IHTMLMimeTypesCollection, "[object]");
4628
4629     length = 0xdeadbeef;
4630     hres = IHTMLMimeTypesCollection_get_length(col, &length);
4631     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4632     ok(!length, "length = %d\n", length);
4633
4634     ref = IHTMLMimeTypesCollection_Release(col);
4635     ok(!ref, "ref=%d\n", ref);
4636 }
4637
4638 #define test_framebase_name(a,b) _test_framebase_name(__LINE__,a,b)
4639 static void _test_framebase_name(unsigned line, IHTMLElement *elem, const char *name)
4640 {
4641     BSTR str = (void*)0xdeadbeef;
4642     IHTMLFrameBase *fbase;
4643     HRESULT hres;
4644
4645     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
4646     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
4647
4648     hres = IHTMLFrameBase_get_name(fbase, &str);
4649     ok_(__FILE__,line)(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
4650     if(name)
4651         ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
4652     else
4653         ok_(__FILE__,line)(!str, "name = %s, expected NULL\n", wine_dbgstr_w(str));
4654     SysFreeString(str);
4655
4656     IHTMLFrameBase_Release(fbase);
4657 }
4658
4659 #define test_framebase_put_name(a,b) _test_framebase_put_name(__LINE__,a,b)
4660 static void _test_framebase_put_name(unsigned line, IHTMLElement *elem, const char *name)
4661 {
4662     IHTMLFrameBase *fbase;
4663     HRESULT hres;
4664     BSTR str;
4665
4666     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
4667     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
4668
4669     str = name ? a2bstr(name) : NULL;
4670     hres = IHTMLFrameBase_put_name(fbase, str);
4671     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
4672     SysFreeString(str);
4673
4674     _test_framebase_name(line, elem, name);
4675     IHTMLFrameBase_Release(fbase);
4676 }
4677
4678 #define test_framebase_marginheight(a,b) _test_framebase_marginheight(__LINE__,a,b)
4679 static void _test_framebase_marginheight(unsigned line, IHTMLFrameBase *framebase, const char *exval)
4680 {
4681     VARIANT v;
4682     HRESULT hres;
4683
4684     hres = IHTMLFrameBase_get_marginHeight(framebase, &v);
4685     ok_(__FILE__,line)(hres == S_OK, "get_marginHeight failed: %08x\n", hres);
4686     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(marginHeight) = %d\n", V_VT(&v));
4687     if(exval)
4688         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "marginHeight = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
4689     else
4690         ok_(__FILE__,line)(!V_BSTR(&v), "marginHeight = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
4691     VariantClear(&v);
4692 }
4693
4694 #define set_framebase_marginheight(a,b) _set_framebase_marginheight(__LINE__,a,b)
4695 static void _set_framebase_marginheight(unsigned line, IHTMLFrameBase *framebase, const char *val)
4696 {
4697     VARIANT v;
4698     HRESULT hres;
4699
4700     V_VT(&v) = VT_BSTR;
4701     V_BSTR(&v) = a2bstr(val);
4702     hres = IHTMLFrameBase_put_marginHeight(framebase, v);
4703     ok_(__FILE__,line)(hres == S_OK, "put_marginHeight failed: %08x\n", hres);
4704     VariantClear(&v);
4705 }
4706
4707 #define test_framebase_marginwidth(a,b) _test_framebase_marginwidth(__LINE__,a,b)
4708 static void _test_framebase_marginwidth(unsigned line, IHTMLFrameBase *framebase, const char *exval)
4709 {
4710     VARIANT v;
4711     HRESULT hres;
4712
4713     hres = IHTMLFrameBase_get_marginWidth(framebase, &v);
4714     ok_(__FILE__,line)(hres == S_OK, "get_marginWidth failed: %08x\n", hres);
4715     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(marginWidth) = %d\n", V_VT(&v));
4716     if(exval)
4717         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "marginWidth = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
4718     else
4719         ok_(__FILE__,line)(!V_BSTR(&v), "marginWidth = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
4720     VariantClear(&v);
4721 }
4722
4723 #define set_framebase_marginwidth(a,b) _set_framebase_marginwidth(__LINE__,a,b)
4724 static void _set_framebase_marginwidth(unsigned line, IHTMLFrameBase *framebase, const char *val)
4725 {
4726     VARIANT v;
4727     HRESULT hres;
4728
4729     V_VT(&v) = VT_BSTR;
4730     V_BSTR(&v) = a2bstr(val);
4731     hres = IHTMLFrameBase_put_marginWidth(framebase, v);
4732     ok_(__FILE__,line)(hres == S_OK, "put_marginWidth failed: %08x\n", hres);
4733     VariantClear(&v);
4734 }
4735
4736 static void test_framebase(IUnknown *unk)
4737 {
4738     IHTMLFrameBase *fbase;
4739     BSTR str;
4740     HRESULT hres;
4741
4742     /* get/put scrolling */
4743     hres = IUnknown_QueryInterface(unk, &IID_IHTMLFrameBase, (void**)&fbase);
4744     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
4745
4746     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
4747     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
4748     ok(!strcmp_wa(str, "auto"), "get_scrolling should have given 'auto', gave: %s\n", wine_dbgstr_w(str));
4749     SysFreeString(str);
4750
4751     str = a2bstr("no");
4752     hres = IHTMLFrameBase_put_scrolling(fbase, str);
4753     ok(hres == S_OK, "IHTMLFrameBase_put_scrolling failed: 0x%08x\n", hres);
4754     SysFreeString(str);
4755
4756     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
4757     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
4758     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
4759     SysFreeString(str);
4760
4761     str = a2bstr("junk");
4762     hres = IHTMLFrameBase_put_scrolling(fbase, str);
4763     ok(hres == E_INVALIDARG, "IHTMLFrameBase_put_scrolling should have failed "
4764             "with E_INVALIDARG, instead: 0x%08x\n", hres);
4765     SysFreeString(str);
4766
4767     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
4768     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
4769     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
4770     SysFreeString(str);
4771
4772     hres = IHTMLFrameBase_get_frameBorder(fbase, &str);
4773     ok(hres == S_OK, "get_frameBorder failed: %08x\n", hres);
4774     ok(!str, "frameBorder = %s\n", wine_dbgstr_w(str));
4775
4776     str = a2bstr("1");
4777     hres = IHTMLFrameBase_put_frameBorder(fbase, str);
4778     ok(hres == S_OK, "put_frameBorder failed: %08x\n", hres);
4779     SysFreeString(str);
4780
4781     hres = IHTMLFrameBase_get_frameBorder(fbase, &str);
4782     ok(hres == S_OK, "get_frameBorder failed: %08x\n", hres);
4783     ok(!strcmp_wa(str, "1"), "frameBorder = %s, expected \"1\"\n", wine_dbgstr_w(str));
4784
4785     test_framebase_marginheight(fbase, NULL);
4786     set_framebase_marginheight(fbase, "1px");
4787     test_framebase_marginheight(fbase, "1");
4788
4789     test_framebase_marginwidth(fbase, NULL);
4790     set_framebase_marginwidth(fbase, "2px");
4791     test_framebase_marginwidth(fbase, "2");
4792
4793     IHTMLFrameBase_Release(fbase);
4794 }
4795
4796 #define test_language_string(a,b) _test_language_string(__LINE__,a,b)
4797 static void _test_language_string(unsigned line, const WCHAR *lang, LCID lcid)
4798 {
4799     WCHAR buf[64];
4800     int res;
4801
4802     if(pLCIDToLocaleName) {
4803         res = pLCIDToLocaleName(lcid, buf, sizeof(buf)/sizeof(WCHAR), 0);
4804         ok_(__FILE__,line)(res, "LCIDToLocaleName failed: %u\n", GetLastError());
4805         ok_(__FILE__,line)(!lstrcmpW(lang, buf), "lang = %s, expected %s\n", wine_dbgstr_w(lang), wine_dbgstr_w(buf));
4806     }else {
4807         win_skip("LCIDToLocaleName not available, unable to test language string\n");
4808         ok_(__FILE__,line)(lang != NULL, "lang == NULL\n");
4809     }
4810 }
4811
4812 static void test_navigator(IHTMLDocument2 *doc)
4813 {
4814     IHTMLWindow2 *window;
4815     IOmNavigator *navigator, *navigator2;
4816     VARIANT_BOOL b;
4817     char buf[512];
4818     DWORD size;
4819     ULONG ref;
4820     BSTR bstr;
4821     HRESULT hres;
4822
4823     static const WCHAR v40[] = {'4','.','0'};
4824
4825     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4826     ok(hres == S_OK, "parentWidnow failed: %08x\n", hres);
4827
4828     hres = IHTMLWindow2_get_navigator(window, &navigator);
4829     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
4830     ok(navigator != NULL, "navigator == NULL\n");
4831     test_disp2((IUnknown*)navigator, &DIID_DispHTMLNavigator, &IID_IOmNavigator, "[object]");
4832
4833     hres = IHTMLWindow2_get_navigator(window, &navigator2);
4834     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
4835     ok(navigator != navigator2, "navigator2 != navihgator\n");
4836
4837     IHTMLWindow2_Release(window);
4838     IOmNavigator_Release(navigator2);
4839
4840     hres = IOmNavigator_get_appCodeName(navigator, &bstr);
4841     ok(hres == S_OK, "get_appCodeName failed: %08x\n", hres);
4842     ok(!strcmp_wa(bstr, "Mozilla"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
4843     SysFreeString(bstr);
4844
4845     bstr = NULL;
4846     hres = IOmNavigator_get_appName(navigator, &bstr);
4847     ok(hres == S_OK, "get_appName failed: %08x\n", hres);
4848     ok(!strcmp_wa(bstr, "Microsoft Internet Explorer"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
4849     SysFreeString(bstr);
4850
4851     bstr = NULL;
4852     hres = IOmNavigator_get_platform(navigator, &bstr);
4853     ok(hres == S_OK, "get_platform failed: %08x\n", hres);
4854     ok(!strcmp_wa(bstr, sizeof(void*) == 8 ? "Win64" : "Win32")
4855        || (sizeof(void*) == 8 && broken(!strcmp_wa(bstr, "Win32") /* IE6 */)), "unexpected platform %s\n", wine_dbgstr_w(bstr));
4856     SysFreeString(bstr);
4857
4858     bstr = NULL;
4859     hres = IOmNavigator_get_cpuClass(navigator, &bstr);
4860     ok(hres == S_OK, "get_cpuClass failed: %08x\n", hres);
4861     ok(!strcmp_wa(bstr, sizeof(void*) == 8 ? "x64" : "x86"), "unexpected cpuClass %s\n", wine_dbgstr_w(bstr));
4862     SysFreeString(bstr);
4863
4864     bstr = NULL;
4865     hres = IOmNavigator_get_appVersion(navigator, &bstr);
4866     ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
4867     ok(!memcmp(bstr, v40, sizeof(v40)), "appVersion is %s\n", wine_dbgstr_w(bstr));
4868     SysFreeString(bstr);
4869
4870     bstr = NULL;
4871     hres = IOmNavigator_get_systemLanguage(navigator, &bstr);
4872     ok(hres == S_OK, "get_systemLanguage failed: %08x\n", hres);
4873     test_language_string(bstr, LOCALE_SYSTEM_DEFAULT);
4874     SysFreeString(bstr);
4875
4876     if (pGetUserDefaultUILanguage)
4877     {
4878         bstr = NULL;
4879         hres = IOmNavigator_get_browserLanguage(navigator, &bstr);
4880         ok(hres == S_OK, "get_browserLanguage failed: %08x\n", hres);
4881         test_language_string(bstr, pGetUserDefaultUILanguage());
4882         SysFreeString(bstr);
4883     }
4884     else
4885         win_skip("GetUserDefaultUILanguage not available\n");
4886
4887     bstr = NULL;
4888     hres = IOmNavigator_get_userLanguage(navigator, &bstr);
4889     ok(hres == S_OK, "get_userLanguage failed: %08x\n", hres);
4890     test_language_string(bstr, LOCALE_USER_DEFAULT);
4891     SysFreeString(bstr);
4892
4893     hres = IOmNavigator_toString(navigator, NULL);
4894     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
4895
4896     bstr = NULL;
4897     hres = IOmNavigator_toString(navigator, &bstr);
4898     ok(hres == S_OK, "toString failed: %08x\n", hres);
4899     ok(!strcmp_wa(bstr, "[object]"), "toString returned %s\n", wine_dbgstr_w(bstr));
4900     SysFreeString(bstr);
4901
4902     b = 100;
4903     hres = IOmNavigator_get_onLine(navigator, &b);
4904     ok(hres == S_OK, "get_onLine failed: %08x\n", hres);
4905     ok(b == VARIANT_TRUE, "onLine = %x\n", b);
4906
4907     size = sizeof(buf);
4908     hres = ObtainUserAgentString(0, buf, &size);
4909     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
4910
4911     bstr = NULL;
4912     hres = IOmNavigator_get_userAgent(navigator, &bstr);
4913     ok(hres == S_OK, "get_userAgent failed: %08x\n", hres);
4914     ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf);
4915     SysFreeString(bstr);
4916
4917     if(!strncmp(buf, "Mozilla/", 8)) {
4918         bstr = NULL;
4919         hres = IOmNavigator_get_appVersion(navigator, &bstr);
4920         ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
4921         ok(!strcmp_wa(bstr, buf+8), "appVersion returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf+8);
4922         SysFreeString(bstr);
4923     }else {
4924         skip("nonstandard user agent\n");
4925     }
4926
4927     bstr = NULL;
4928     hres = IOmNavigator_get_appMinorVersion(navigator, &bstr);
4929     ok(hres == S_OK, "get_appMonorVersion failed: %08x\n", hres);
4930     ok(bstr != NULL, "appMinorVersion returned NULL\n");
4931     SysFreeString(bstr);
4932
4933     test_mime_types_col(navigator);
4934
4935     ref = IOmNavigator_Release(navigator);
4936     ok(!ref, "navigator should be destroyed here\n");
4937 }
4938
4939 static void test_screen(IHTMLWindow2 *window)
4940 {
4941     IHTMLScreen *screen, *screen2;
4942     IDispatchEx *dispex;
4943     RECT work_area;
4944     LONG l, exl;
4945     HDC hdc;
4946     HRESULT hres;
4947
4948     screen = NULL;
4949     hres = IHTMLWindow2_get_screen(window, &screen);
4950     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
4951     ok(screen != NULL, "screen == NULL\n");
4952
4953     screen2 = NULL;
4954     hres = IHTMLWindow2_get_screen(window, &screen2);
4955     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
4956     ok(screen2 != NULL, "screen == NULL\n");
4957     ok(iface_cmp((IUnknown*)screen2, (IUnknown*)screen), "screen2 != screen\n");
4958     IHTMLScreen_Release(screen2);
4959
4960     hres = IHTMLScreen_QueryInterface(screen, &IID_IDispatchEx, (void**)&dispex);
4961     ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres);
4962     if(SUCCEEDED(hres)) {
4963         test_disp((IUnknown*)screen, &DIID_DispHTMLScreen, "[object]");
4964         IDispatchEx_Release(dispex);
4965     }
4966
4967     hdc = CreateICA("DISPLAY", NULL, NULL, NULL);
4968
4969     exl = GetDeviceCaps(hdc, HORZRES);
4970     l = 0xdeadbeef;
4971     hres = IHTMLScreen_get_width(screen, &l);
4972     ok(hres == S_OK, "get_width failed: %08x\n", hres);
4973     ok(l == exl, "width = %d, expected %d\n", l, exl);
4974
4975     exl = GetDeviceCaps(hdc, VERTRES);
4976     l = 0xdeadbeef;
4977     hres = IHTMLScreen_get_height(screen, &l);
4978     ok(hres == S_OK, "get_height failed: %08x\n", hres);
4979     ok(l == exl, "height = %d, expected %d\n", l, exl);
4980
4981     exl = GetDeviceCaps(hdc, BITSPIXEL);
4982     l = 0xdeadbeef;
4983     hres = IHTMLScreen_get_colorDepth(screen, &l);
4984     ok(hres == S_OK, "get_height failed: %08x\n", hres);
4985     ok(l == exl, "height = %d, expected %d\n", l, exl);
4986
4987     DeleteObject(hdc);
4988
4989     SystemParametersInfoW(SPI_GETWORKAREA, 0, &work_area, 0);
4990
4991     l = 0xdeadbeef;
4992     hres = IHTMLScreen_get_availHeight(screen, &l);
4993     ok(hres == S_OK, "get_availHeight failed: %08x\n", hres);
4994     ok(l == work_area.bottom-work_area.top, "availHeight = %d, expected %d\n", l, work_area.bottom-work_area.top);
4995
4996     l = 0xdeadbeef;
4997     hres = IHTMLScreen_get_availWidth(screen, &l);
4998     ok(hres == S_OK, "get_availWidth failed: %08x\n", hres);
4999     ok(l == work_area.right-work_area.left, "availWidth = %d, expected %d\n", l, work_area.right-work_area.left);
5000
5001     IHTMLScreen_Release(screen);
5002 }
5003
5004 static void test_default_selection(IHTMLDocument2 *doc)
5005 {
5006     IHTMLSelectionObject *selection;
5007     IHTMLTxtRange *range;
5008     IDispatch *disp;
5009     BSTR str;
5010     HRESULT hres;
5011
5012     hres = IHTMLDocument2_get_selection(doc, &selection);
5013     ok(hres == S_OK, "get_selection failed: %08x\n", hres);
5014
5015     hres = IHTMLSelectionObject_get_type(selection, &str);
5016     ok(hres == S_OK, "get_type failed: %08x\n", hres);
5017     ok(!strcmp_wa(str, "None"), "type = %s\n", wine_dbgstr_w(str));
5018     SysFreeString(str);
5019
5020     hres = IHTMLSelectionObject_createRange(selection, &disp);
5021     IHTMLSelectionObject_Release(selection);
5022     ok(hres == S_OK, "createRange failed: %08x\n", hres);
5023
5024     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTxtRange, (void**)&range);
5025     IDispatch_Release(disp);
5026     ok(hres == S_OK, "Could not get IHTMLTxtRange interface: %08x\n", hres);
5027
5028     test_range_text(range, NULL);
5029     IHTMLTxtRange_Release(range);
5030 }
5031
5032 static void test_doc_elem(IHTMLDocument2 *doc)
5033 {
5034     IHTMLDocument2 *doc_node, *owner_doc;
5035     IHTMLElement *elem;
5036     IHTMLDocument3 *doc3;
5037     HRESULT hres;
5038
5039     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
5040     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
5041
5042     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
5043     IHTMLDocument3_Release(doc3);
5044     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
5045
5046     test_node_name((IUnknown*)elem, "HTML");
5047     test_elem_tag((IUnknown*)elem, "HTML");
5048
5049     doc_node = get_doc_node(doc);
5050     owner_doc = get_owner_doc((IUnknown*)elem);
5051     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
5052     IHTMLDocument2_Release(owner_doc);
5053
5054     owner_doc = get_owner_doc((IUnknown*)doc_node);
5055     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
5056     IHTMLDocument2_Release(doc_node);
5057
5058     test_elem_client_rect((IUnknown*)elem);
5059
5060     IHTMLElement_Release(elem);
5061 }
5062
5063 static void test_default_body(IHTMLBodyElement *body)
5064 {
5065     LONG l;
5066     BSTR bstr;
5067     HRESULT hres;
5068     VARIANT v;
5069
5070     bstr = (void*)0xdeadbeef;
5071     hres = IHTMLBodyElement_get_background(body, &bstr);
5072     ok(hres == S_OK, "get_background failed: %08x\n", hres);
5073     ok(bstr == NULL, "bstr != NULL\n");
5074
5075     l = elem_get_scroll_height((IUnknown*)body);
5076     ok(l != -1, "scrollHeight == -1\n");
5077     l = elem_get_scroll_width((IUnknown*)body);
5078     ok(l != -1, "scrollWidth == -1\n");
5079     l = elem_get_scroll_top((IUnknown*)body);
5080     ok(!l, "scrollTop = %d\n", l);
5081     elem_get_scroll_left((IUnknown*)body);
5082
5083     /* get_text tests */
5084     hres = IHTMLBodyElement_get_text(body, &v);
5085     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
5086     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
5087     ok(V_BSTR(&v) == NULL, "bstr != NULL\n");
5088
5089     /* get_text - Invalid Text */
5090     V_VT(&v) = VT_BSTR;
5091     V_BSTR(&v) = a2bstr("Invalid");
5092     hres = IHTMLBodyElement_put_text(body, v);
5093     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
5094     VariantClear(&v);
5095
5096     V_VT(&v) = VT_NULL;
5097     hres = IHTMLBodyElement_get_text(body, &v);
5098     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
5099     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
5100     ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v = %s, expected '#00a0d0'\n", wine_dbgstr_w(V_BSTR(&v)));
5101     VariantClear(&v);
5102
5103     /* get_text - Valid Text */
5104     V_VT(&v) = VT_BSTR;
5105     V_BSTR(&v) = a2bstr("#FF0000");
5106     hres = IHTMLBodyElement_put_text(body, v);
5107     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
5108     VariantClear(&v);
5109
5110     V_VT(&v) = VT_NULL;
5111     hres = IHTMLBodyElement_get_text(body, &v);
5112     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
5113     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
5114     ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v = %s, expected '#ff0000'\n", wine_dbgstr_w(V_BSTR(&v)));
5115     VariantClear(&v);
5116 }
5117
5118 static void test_body_funs(IHTMLBodyElement *body)
5119 {
5120     VARIANT vbg, vDefaultbg;
5121     HRESULT hres;
5122
5123     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
5124     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
5125     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
5126     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
5127
5128     V_VT(&vbg) = VT_BSTR;
5129     V_BSTR(&vbg) = a2bstr("red");
5130     hres = IHTMLBodyElement_put_bgColor(body, vbg);
5131     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
5132     VariantClear(&vbg);
5133
5134     hres = IHTMLBodyElement_get_bgColor(body, &vbg);
5135     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
5136     ok(V_VT(&vDefaultbg) == VT_BSTR, "V_VT(&vDefaultbg) != VT_BSTR\n");
5137     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
5138     VariantClear(&vbg);
5139
5140     /* Restore Originial */
5141     hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg);
5142     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
5143     VariantClear(&vDefaultbg);
5144 }
5145
5146 static void test_history(IHTMLWindow2 *window)
5147 {
5148     IOmHistory *history, *history2;
5149     HRESULT hres;
5150
5151     history = NULL;
5152     hres = IHTMLWindow2_get_history(window, &history);
5153     ok(hres == S_OK, "get_history failed: %08x\n", hres);
5154     ok(history != NULL, "history = NULL\n");
5155
5156     test_disp2((IUnknown*)history, &DIID_DispHTMLHistory, &IID_IOmHistory, "[object]");
5157
5158     history2 = NULL;
5159     hres = IHTMLWindow2_get_history(window, &history2);
5160     ok(hres == S_OK, "get_history failed: %08x\n", hres);
5161     ok(history2 != NULL, "history2 = NULL\n");
5162     ok(iface_cmp((IUnknown*)history, (IUnknown*)history2), "history != history2\n");
5163
5164     IOmHistory_Release(history2);
5165     IOmHistory_Release(history);
5166 }
5167
5168 static void test_window(IHTMLDocument2 *doc)
5169 {
5170     IHTMLWindow2 *window, *window2, *self, *parent;
5171     IHTMLDocument2 *doc2 = NULL;
5172     IDispatch *disp;
5173     IUnknown *unk;
5174     VARIANT v;
5175     BSTR str;
5176     HRESULT hres;
5177
5178     hres = IHTMLDocument2_get_parentWindow(doc, &window);
5179     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
5180     test_ifaces((IUnknown*)window, window_iids);
5181     hres = IHTMLWindow2_QueryInterface(window, &IID_ITravelLogClient, (void**)&unk);
5182     if(hres == S_OK)
5183         IUnknown_Release(unk);
5184     else
5185         win_skip("IID_ITravelLogClient not supported\n");
5186
5187     test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, "[object]");
5188
5189     hres = IHTMLWindow2_get_document(window, &doc2);
5190     ok(hres == S_OK, "get_document failed: %08x\n", hres);
5191     ok(doc2 != NULL, "doc2 == NULL\n");
5192
5193     test_ifaces((IUnknown*)doc2, doc_node_iids);
5194     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
5195     test_class_info((IUnknown*)doc2);
5196
5197     test_ifaces((IUnknown*)doc, doc_obj_iids);
5198     test_disp((IUnknown*)doc, &DIID_DispHTMLDocument, "[object]");
5199     test_class_info((IUnknown*)doc);
5200
5201     unk = (void*)0xdeadbeef;
5202     hres = IHTMLDocument2_QueryInterface(doc2, &IID_ICustomDoc, (void**)&unk);
5203     ok(hres == E_NOINTERFACE, "QueryInterface(IID_ICustomDoc) returned: %08x\n", hres);
5204     ok(!unk, "unk = %p\n", unk);
5205
5206     IHTMLDocument2_Release(doc2);
5207
5208     hres = IHTMLWindow2_get_window(window, &window2);
5209     ok(hres == S_OK, "get_window failed: %08x\n", hres);
5210     ok(window2 != NULL, "window2 == NULL\n");
5211
5212     hres = IHTMLWindow2_get_self(window, &self);
5213     ok(hres == S_OK, "get_self failed: %08x\n", hres);
5214     ok(window2 != NULL, "self == NULL\n");
5215
5216     ok(self == window2, "self != window2\n");
5217
5218     IHTMLWindow2_Release(window2);
5219
5220     disp = NULL;
5221     hres = IHTMLDocument2_get_Script(doc, &disp);
5222     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
5223     ok(disp == (void*)window, "disp != window\n");
5224     IDispatch_Release(disp);
5225
5226     hres = IHTMLWindow2_toString(window, NULL);
5227     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
5228
5229     str = NULL;
5230     hres = IHTMLWindow2_toString(window, &str);
5231     ok(hres == S_OK, "toString failed: %08x\n", hres);
5232     ok(!strcmp_wa(str, "[object]") ||
5233        !strcmp_wa(str, "[object Window]") /* win7 ie9 */, "toString returned %s\n", wine_dbgstr_w(str));
5234     SysFreeString(str);
5235
5236     V_VT(&v) = VT_ERROR;
5237     hres = IHTMLWindow2_get_opener(window, &v);
5238     ok(hres == S_OK, "get_opener failed: %08x\n", hres);
5239     ok(V_VT(&v) == VT_EMPTY, "V_VT(opener) = %d\n", V_VT(&v));
5240
5241     parent = NULL;
5242     hres = IHTMLWindow2_get_parent(window, &parent);
5243     ok(hres == S_OK, "get_parent failed: %08x\n", hres);
5244     ok(parent != NULL, "parent == NULL\n");
5245     ok(parent == self, "parent != window\n");
5246     IHTMLWindow2_Release(parent);
5247     IHTMLWindow2_Release(self);
5248
5249     test_window_name(window, NULL);
5250     set_window_name(window, "test");
5251     test_window_length(window, 0);
5252     test_screen(window);
5253     test_window_status(window);
5254     set_window_status(window, "Test!");
5255     test_history(window);
5256
5257     IHTMLWindow2_Release(window);
5258 }
5259
5260 static void test_defaults(IHTMLDocument2 *doc)
5261 {
5262     IHTMLStyleSheetsCollection *stylesheetcol;
5263     IHTMLCurrentStyle *cstyle;
5264     IHTMLBodyElement *body;
5265     IHTMLElement2 *elem2;
5266     IHTMLElement *elem;
5267     IHTMLStyle *style;
5268     BSTR str;
5269     LONG l;
5270     HRESULT hres;
5271     IHTMLElementCollection *collection;
5272
5273     elem = doc_get_body(doc);
5274
5275     hres = IHTMLDocument2_get_images(doc, NULL);
5276     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5277
5278     hres = IHTMLDocument2_get_images(doc, &collection);
5279     ok(hres == S_OK, "get_images failed: %08x\n", hres);
5280     if(hres == S_OK)
5281     {
5282         test_elem_collection((IUnknown*)collection, NULL, 0);
5283         IHTMLElementCollection_Release(collection);
5284     }
5285
5286     hres = IHTMLDocument2_get_applets(doc, NULL);
5287     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5288
5289     hres = IHTMLDocument2_get_applets(doc, &collection);
5290     ok(hres == S_OK, "get_applets failed: %08x\n", hres);
5291     if(hres == S_OK)
5292     {
5293         test_elem_collection((IUnknown*)collection, NULL, 0);
5294         IHTMLElementCollection_Release(collection);
5295     }
5296
5297     hres = IHTMLDocument2_get_links(doc, NULL);
5298     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5299
5300     hres = IHTMLDocument2_get_links(doc, &collection);
5301     ok(hres == S_OK, "get_links failed: %08x\n", hres);
5302     if(hres == S_OK)
5303     {
5304         test_elem_collection((IUnknown*)collection, NULL, 0);
5305         IHTMLElementCollection_Release(collection);
5306     }
5307
5308     hres = IHTMLDocument2_get_forms(doc, NULL);
5309     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5310
5311     hres = IHTMLDocument2_get_forms(doc, &collection);
5312     ok(hres == S_OK, "get_forms failed: %08x\n", hres);
5313     if(hres == S_OK)
5314     {
5315         test_elem_collection((IUnknown*)collection, NULL, 0);
5316         IHTMLElementCollection_Release(collection);
5317     }
5318
5319     hres = IHTMLDocument2_get_anchors(doc, NULL);
5320     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5321
5322     hres = IHTMLDocument2_get_anchors(doc, &collection);
5323     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5324     if(hres == S_OK)
5325     {
5326         test_elem_collection((IUnknown*)collection, NULL, 0);
5327         IHTMLElementCollection_Release(collection);
5328     }
5329
5330     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
5331     ok(hres == S_OK, "Could not get IHTMBodyElement: %08x\n", hres);
5332     test_default_body(body);
5333     test_body_funs(body);
5334     IHTMLBodyElement_Release(body);
5335
5336     hres = IHTMLElement_get_style(elem, &style);
5337     ok(hres == S_OK, "get_style failed: %08x\n", hres);
5338
5339     test_disp((IUnknown*)style, &DIID_DispHTMLStyle, "[object]");
5340     test_ifaces((IUnknown*)style, style_iids);
5341     IHTMLStyle_Release(style);
5342
5343     str = NULL;
5344     hres = IHTMLDocument2_get_charset(doc, &str);
5345     ok(hres == S_OK, "get_charset failed: %08x\n", hres);
5346     ok(str && *str, "charset is empty\n"); /* FIXME: better tests */
5347     SysFreeString(str);
5348
5349     test_window(doc);
5350     test_compatmode(doc, "BackCompat");
5351     test_location(doc);
5352     test_navigator(doc);
5353     test_plugins_col(doc);
5354
5355     elem2 = get_elem2_iface((IUnknown*)elem);
5356     hres = IHTMLElement2_get_currentStyle(elem2, &cstyle);
5357     ok(hres == S_OK, "get_currentStyle failed: %08x\n", hres);
5358     if(SUCCEEDED(hres)) {
5359         IUnknown *unk;
5360
5361         test_disp((IUnknown*)cstyle, &DIID_DispHTMLCurrentStyle, "[object]");
5362         test_ifaces((IUnknown*)cstyle, cstyle_iids);
5363
5364         hres = IHTMLCurrentStyle_QueryInterface(cstyle, &IID_IHTMLCurrentStyle4, (void**)&unk);
5365         if(SUCCEEDED(hres))
5366             IUnknown_Release(unk);
5367         else
5368         {
5369            /*IE6 doesn't have interface */
5370            win_skip("IID_IHTMLCurrentStyle4 not supported\n");
5371         }
5372
5373         IHTMLCurrentStyle_Release(cstyle);
5374     }
5375     IHTMLElement2_Release(elem2);
5376
5377     IHTMLElement_Release(elem);
5378
5379     hres = IHTMLDocument2_get_styleSheets(doc, &stylesheetcol);
5380     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5381
5382     l = 0xdeadbeef;
5383     hres = IHTMLStyleSheetsCollection_get_length(stylesheetcol, &l);
5384     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5385     ok(l == 0, "length = %d\n", l);
5386
5387     IHTMLStyleSheetsCollection_Release(stylesheetcol);
5388
5389     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFiltersCollection, (void**)&body);
5390     ok(hres == E_NOINTERFACE, "got interface IHTMLFiltersCollection\n");
5391
5392     test_default_selection(doc);
5393     test_doc_title(doc, "");
5394 }
5395
5396 #define test_button_name(a,b) _test_button_name(__LINE__,a,b)
5397 static void _test_button_name(unsigned line, IHTMLElement *elem, const char *exname)
5398 {
5399     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
5400     BSTR str;
5401     HRESULT hres;
5402
5403     str = (void*)0xdeadbeef;
5404     hres = IHTMLButtonElement_get_name(button, &str);
5405     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
5406     if(exname)
5407         ok_(__FILE__,line)(!strcmp_wa(str, exname), "name = %s, expected %s\n", wine_dbgstr_w(str), exname);
5408     else
5409         ok_(__FILE__,line)(!str, "name = %s, expected NULL\n", wine_dbgstr_w(str));
5410     SysFreeString(str);
5411     IHTMLButtonElement_Release(button);
5412 }
5413
5414 #define set_button_name(a,b) _set_button_name(__LINE__,a,b)
5415 static void _set_button_name(unsigned line, IHTMLElement *elem, const char *name)
5416 {
5417     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
5418     BSTR str = a2bstr(name);
5419     HRESULT hres;
5420
5421     hres = IHTMLButtonElement_put_name(button, str);
5422     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
5423     SysFreeString(str);
5424     IHTMLButtonElement_Release(button);
5425
5426     _test_button_name(line, elem, name);
5427 }
5428
5429 #define test_button_get_disabled(i,b) _test_button_get_disabled(__LINE__,i,b)
5430 static void _test_button_get_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
5431 {
5432     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
5433     VARIANT_BOOL disabled = 100;
5434     HRESULT hres;
5435
5436     hres = IHTMLButtonElement_get_disabled(button, &disabled);
5437     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
5438     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
5439     IHTMLButtonElement_Release(button);
5440
5441     _test_elem3_get_disabled(line, (IUnknown*)elem, exb);
5442 }
5443
5444 #define test_button_set_disabled(i,b) _test_button_set_disabled(__LINE__,i,b)
5445 static void _test_button_set_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL b)
5446 {
5447     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
5448     HRESULT hres;
5449
5450     hres = IHTMLButtonElement_put_disabled(button, b);
5451     ok_(__FILE__,line) (hres == S_OK, "put_disabled failed: %08x\n", hres);
5452     IHTMLButtonElement_Release(button);
5453
5454     _test_button_get_disabled(line, elem, b);
5455 }
5456
5457 static void test_button_elem(IHTMLElement *elem)
5458 {
5459     test_button_name(elem, NULL);
5460     set_button_name(elem, "button name");
5461 }
5462
5463 static void test_tr_elem(IHTMLElement *elem)
5464 {
5465     IHTMLElementCollection *col;
5466     IHTMLTableRow *row;
5467     HRESULT hres;
5468
5469     static const elem_type_t cell_types[] = {ET_TD,ET_TD};
5470
5471     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableRow, (void**)&row);
5472     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
5473     if(FAILED(hres))
5474         return;
5475
5476     col = NULL;
5477     hres = IHTMLTableRow_get_cells(row, &col);
5478     ok(hres == S_OK, "get_cells failed: %08x\n", hres);
5479     ok(col != NULL, "get_cells returned NULL\n");
5480
5481     test_elem_collection((IUnknown*)col, cell_types, sizeof(cell_types)/sizeof(*cell_types));
5482     IHTMLElementCollection_Release(col);
5483
5484     IHTMLTableRow_Release(row);
5485 }
5486
5487 static void test_table_elem(IHTMLElement *elem)
5488 {
5489     IHTMLElementCollection *col;
5490     IHTMLTable *table;
5491     IHTMLDOMNode *node;
5492     HRESULT hres;
5493
5494     static const elem_type_t row_types[] = {ET_TR,ET_TR};
5495     static const elem_type_t all_types[] = {ET_TBODY,ET_TR,ET_TR,ET_TD,ET_TD};
5496     static const elem_type_t tbodies_types[] = {ET_TBODY};
5497
5498     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable, (void**)&table);
5499     ok(hres == S_OK, "Could not get IHTMLTable iface: %08x\n", hres);
5500     if(FAILED(hres))
5501         return;
5502
5503     col = NULL;
5504     hres = IHTMLTable_get_rows(table, &col);
5505     ok(hres == S_OK, "get_rows failed: %08x\n", hres);
5506     ok(col != NULL, "get_rows returned NULL\n");
5507
5508     test_elem_collection((IUnknown*)col, row_types, sizeof(row_types)/sizeof(*row_types));
5509     IHTMLElementCollection_Release(col);
5510
5511     test_elem_all((IUnknown*)table, all_types, sizeof(all_types)/sizeof(*all_types));
5512
5513     node = clone_node((IUnknown*)table, VARIANT_TRUE);
5514     test_elem_tag((IUnknown*)node, "TABLE");
5515     test_elem_all((IUnknown*)node, all_types, sizeof(all_types)/sizeof(*all_types));
5516     IHTMLDOMNode_Release(node);
5517
5518     node = clone_node((IUnknown*)table, VARIANT_FALSE);
5519     test_elem_tag((IUnknown*)node, "TABLE");
5520     test_elem_all((IUnknown*)node, NULL, 0);
5521     IHTMLDOMNode_Release(node);
5522
5523     col = NULL;
5524     hres = IHTMLTable_get_tBodies(table, &col);
5525     ok(hres == S_OK, "get_tBodies failed: %08x\n", hres);
5526     ok(col != NULL, "get_tBodies returned NULL\n");
5527
5528     test_elem_collection((IUnknown*)col, tbodies_types, sizeof(tbodies_types)/sizeof(*tbodies_types));
5529     IHTMLElementCollection_Release(col);
5530
5531     IHTMLTable_Release(table);
5532 }
5533
5534 static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
5535 {
5536     SAFEARRAYBOUND dim;
5537     SAFEARRAY *sa;
5538     VARIANT *var;
5539     HRESULT hres;
5540
5541     dim.lLbound = 0;
5542     dim.cElements = 1;
5543     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
5544     SafeArrayAccessData(sa, (void**)&var);
5545     V_VT(var) = VT_BSTR;
5546     V_BSTR(var) = a2bstr(text);
5547     SafeArrayUnaccessData(sa);
5548
5549     if(ln)
5550         hres = IHTMLDocument2_writeln(doc, sa);
5551     else
5552         hres = IHTMLDocument2_write(doc, sa);
5553     ok(hres == S_OK, "write failed: %08x\n", hres);
5554
5555     SafeArrayDestroy(sa);
5556 }
5557
5558 static void doc_complex_write(IHTMLDocument2 *doc)
5559 {
5560     SAFEARRAYBOUND dim = {5, 0};
5561     SAFEARRAY *sa;
5562     VARIANT *args;
5563     HRESULT hres;
5564
5565     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
5566     SafeArrayAccessData(sa, (void**)&args);
5567
5568     V_VT(args) = VT_BSTR;
5569     V_BSTR(args) = a2bstr("<body i4val=\"");
5570     V_VT(args+1) = VT_I4;
5571     V_I4(args+1) = 4;
5572     V_VT(args+2) = VT_BSTR;
5573     V_BSTR(args+2) = a2bstr("\" r8val=\"");
5574     V_VT(args+3) = VT_R8;
5575     V_R8(args+3) = 3.14;
5576     V_VT(args+4) = VT_BSTR;
5577     V_BSTR(args+4) = a2bstr("\">");
5578     SafeArrayUnaccessData(sa);
5579
5580     hres = IHTMLDocument2_write(doc, sa);
5581     ok(hres == S_OK, "write failed: %08x\n", hres);
5582
5583     SafeArrayDestroy(sa);
5584 }
5585
5586 static void test_frame_doc(IUnknown *frame_elem, BOOL iframe)
5587 {
5588     IHTMLDocument2 *window_doc, *elem_doc;
5589     IHTMLFrameElement3 *frame_elem3;
5590     IHTMLWindow2 *content_window;
5591     HRESULT hres;
5592
5593     content_window = get_frame_content_window(frame_elem);
5594     test_ifaces((IUnknown*)content_window, window_iids);
5595     window_doc = get_window_doc(content_window);
5596     IHTMLWindow2_Release(content_window);
5597
5598     elem_doc = get_elem_doc(frame_elem);
5599     ok(iface_cmp((IUnknown*)window_doc, (IUnknown*)elem_doc), "content_doc != elem_doc\n");
5600
5601     if(!iframe) {
5602         hres = IUnknown_QueryInterface(frame_elem, &IID_IHTMLFrameElement3, (void**)&frame_elem3);
5603         if(SUCCEEDED(hres)) {
5604             IDispatch *disp = NULL;
5605
5606             hres = IHTMLFrameElement3_get_contentDocument(frame_elem3, &disp);
5607             ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
5608             ok(disp != NULL, "contentDocument == NULL\n");
5609             ok(iface_cmp((IUnknown*)disp, (IUnknown*)window_doc), "contentDocument != contentWindow.document\n");
5610
5611             IDispatch_Release(disp);
5612             IHTMLFrameElement3_Release(frame_elem3);
5613         }else {
5614             win_skip("IHTMLFrameElement3 not supported\n");
5615         }
5616     }
5617
5618     IHTMLDocument2_Release(elem_doc);
5619     IHTMLDocument2_Release(window_doc);
5620 }
5621
5622 #define test_iframe_height(a,b) _test_iframe_height(__LINE__,a,b)
5623 static void _test_iframe_height(unsigned line, IHTMLElement *elem, const char *exval)
5624 {
5625     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5626     VARIANT v;
5627     HRESULT hres;
5628
5629     hres = IHTMLIFrameElement2_get_height(iframe, &v);
5630     ok_(__FILE__,line)(hres == S_OK, "get_height failed: %08x\n", hres);
5631     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(height) = %d\n", V_VT(&v));
5632     if(exval)
5633         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "height = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
5634     else
5635         ok_(__FILE__,line)(!V_BSTR(&v), "height = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
5636     VariantClear(&v);
5637     IHTMLIFrameElement2_Release(iframe);
5638 }
5639
5640 #define set_iframe_height(a,b) _set_iframe_height(__LINE__,a,b)
5641 static void _set_iframe_height(unsigned line, IHTMLElement *elem, const char *val)
5642 {
5643     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5644     VARIANT v;
5645     HRESULT hres;
5646
5647     V_VT(&v) = VT_BSTR;
5648     V_BSTR(&v) = a2bstr(val);
5649     hres = IHTMLIFrameElement2_put_height(iframe, v);
5650     ok_(__FILE__,line)(hres == S_OK, "put_height failed: %08x\n", hres);
5651     VariantClear(&v);
5652     IHTMLIFrameElement2_Release(iframe);
5653 }
5654
5655 #define test_iframe_width(a,b) _test_iframe_width(__LINE__,a,b)
5656 static void _test_iframe_width(unsigned line, IHTMLElement *elem, const char *exval)
5657 {
5658     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5659     VARIANT v;
5660     HRESULT hres;
5661
5662     hres = IHTMLIFrameElement2_get_width(iframe, &v);
5663     ok_(__FILE__,line)(hres == S_OK, "get_width failed: %08x\n", hres);
5664     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(width) = %d\n", V_VT(&v));
5665     if(exval)
5666         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "width = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
5667     else
5668         ok_(__FILE__,line)(!V_BSTR(&v), "width = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
5669     VariantClear(&v);
5670     IHTMLIFrameElement2_Release(iframe);
5671 }
5672
5673 #define set_iframe_width(a,b) _set_iframe_width(__LINE__,a,b)
5674 static void _set_iframe_width(unsigned line, IHTMLElement *elem, const char *val)
5675 {
5676     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5677     VARIANT v;
5678     HRESULT hres;
5679
5680     V_VT(&v) = VT_BSTR;
5681     V_BSTR(&v) = a2bstr(val);
5682     hres = IHTMLIFrameElement2_put_width(iframe, v);
5683     ok_(__FILE__,line)(hres == S_OK, "put_width failed: %08x\n", hres);
5684     VariantClear(&v);
5685     IHTMLIFrameElement2_Release(iframe);
5686 }
5687
5688 static void test_iframe_elem(IHTMLElement *elem)
5689 {
5690     IHTMLDocument2 *content_doc, *owner_doc;
5691     IHTMLIFrameElement3 *iframe3;
5692     IHTMLElementCollection *col;
5693     IHTMLWindow2 *content_window;
5694     IHTMLElement *body;
5695     IDispatch *disp;
5696     VARIANT errv;
5697     BSTR str;
5698     HRESULT hres;
5699
5700     static const elem_type_t all_types[] = {
5701         ET_HTML,
5702         ET_HEAD,
5703         ET_TITLE,
5704         ET_BODY,
5705         ET_BR
5706     };
5707
5708     test_frame_doc((IUnknown*)elem, TRUE);
5709     test_framebase((IUnknown*)elem);
5710
5711     content_window = get_frame_content_window((IUnknown*)elem);
5712     test_ifaces((IUnknown*)content_window, window_iids);
5713     test_window_length(content_window, 0);
5714
5715     content_doc = get_window_doc(content_window);
5716     IHTMLWindow2_Release(content_window);
5717
5718     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLIFrameElement3, (void**)&iframe3);
5719     if(SUCCEEDED(hres)) {
5720         hres = IHTMLIFrameElement3_get_contentDocument(iframe3, &disp);
5721         ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
5722         ok(iface_cmp((IUnknown*)content_doc, (IUnknown*)disp), "content_doc != disp\n");
5723         IDispatch_Release(disp);
5724
5725         IHTMLIFrameElement3_Release(iframe3);
5726     }else {
5727         win_skip("IHTMLIFrameElement3 not supported\n");
5728     }
5729
5730     test_iframe_height(elem, NULL);
5731     set_iframe_height(elem, "100px");
5732     set_iframe_height(elem, "50%");
5733     test_iframe_height(elem, "50%");
5734
5735     test_iframe_width(elem, NULL);
5736     set_iframe_width(elem, "150px");
5737     set_iframe_width(elem, "70%");
5738     test_iframe_width(elem, "70%");
5739
5740     str = a2bstr("text/html");
5741     V_VT(&errv) = VT_ERROR;
5742     disp = NULL;
5743     hres = IHTMLDocument2_open(content_doc, str, errv, errv, errv, &disp);
5744     SysFreeString(str);
5745     ok(hres == S_OK, "open failed: %08x\n", hres);
5746     ok(disp != NULL, "disp == NULL\n");
5747     ok(iface_cmp((IUnknown*)disp, (IUnknown*)content_window), "disp != content_window\n");
5748     IDispatch_Release(disp);
5749
5750     doc_write(content_doc, FALSE, "<html><head><title>test</title></head>");
5751     doc_complex_write(content_doc);
5752     doc_write(content_doc, TRUE, "<br />");
5753     doc_write(content_doc, TRUE, "</html>");
5754
5755     hres = IHTMLDocument2_get_all(content_doc, &col);
5756     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5757     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5758     IHTMLElementCollection_Release(col);
5759
5760     body = doc_get_body(content_doc);
5761     test_elem_attr(body, "i4val", "4");
5762     test_elem_attr(body, "r8val", "3.14");
5763     IHTMLElement_Release(body);
5764
5765     hres = IHTMLDocument2_close(content_doc);
5766     ok(hres == S_OK, "close failed: %08x\n", hres);
5767
5768     owner_doc = get_owner_doc((IUnknown*)content_doc);
5769     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
5770
5771     IHTMLDocument2_Release(content_doc);
5772 }
5773
5774 static void test_stylesheet(IDispatch *disp)
5775 {
5776     IHTMLStyleSheetRulesCollection *col = NULL;
5777     IHTMLStyleSheet *stylesheet;
5778     HRESULT hres;
5779
5780     hres = IDispatch_QueryInterface(disp, &IID_IHTMLStyleSheet, (void**)&stylesheet);
5781     ok(hres == S_OK, "Could not get IHTMLStyleSheet: %08x\n", hres);
5782
5783     hres = IHTMLStyleSheet_get_rules(stylesheet, &col);
5784     ok(hres == S_OK, "get_rules failed: %08x\n", hres);
5785     ok(col != NULL, "col == NULL\n");
5786
5787     IHTMLStyleSheetRulesCollection_Release(col);
5788     IHTMLStyleSheet_Release(stylesheet);
5789 }
5790
5791 static void test_stylesheets(IHTMLDocument2 *doc)
5792 {
5793     IHTMLStyleSheetsCollection *col = NULL;
5794     VARIANT idx, res;
5795     LONG len = 0;
5796     HRESULT hres;
5797
5798     hres = IHTMLDocument2_get_styleSheets(doc, &col);
5799     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5800     ok(col != NULL, "col == NULL\n");
5801
5802     test_disp2((IUnknown*)col, &DIID_DispHTMLStyleSheetsCollection, &IID_IHTMLStyleSheetsCollection, "[object]");
5803
5804     hres = IHTMLStyleSheetsCollection_get_length(col, &len);
5805     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5806     ok(len == 1, "len=%d\n", len);
5807
5808     VariantInit(&res);
5809     V_VT(&idx) = VT_I4;
5810     V_I4(&idx) = 0;
5811
5812     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5813     ok(hres == S_OK, "item failed: %08x\n", hres);
5814     ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
5815     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5816     test_stylesheet(V_DISPATCH(&res));
5817     VariantClear(&res);
5818
5819     V_VT(&res) = VT_I4;
5820     V_VT(&idx) = VT_I4;
5821     V_I4(&idx) = 1;
5822
5823     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5824     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5825     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
5826     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5827     VariantClear(&res);
5828
5829     IHTMLStyleSheetsCollection_Release(col);
5830 }
5831
5832 static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
5833 {
5834     IDispatchEx *dispex;
5835     IHTMLDOMNode *node;
5836     DISPPARAMS dp = {NULL, NULL, 0, 0};
5837     VARIANT var;
5838     EXCEPINFO ei;
5839     LONG type;
5840     DISPID id;
5841     BSTR bstr;
5842     HRESULT hres;
5843
5844     static const WCHAR w0[] = {'0',0};
5845     static const WCHAR w100[] = {'1','0','0',0};
5846
5847     hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
5848     ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
5849
5850     bstr = SysAllocString(w0);
5851     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5852     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5853     SysFreeString(bstr);
5854
5855     VariantInit(&var);
5856     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
5857     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
5858     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
5859     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
5860     node = get_node_iface((IUnknown*)V_DISPATCH(&var));
5861     type = get_node_type((IUnknown*)node);
5862     ok(type == 3, "type=%d\n", type);
5863     IHTMLDOMNode_Release(node);
5864     VariantClear(&var);
5865
5866     bstr = SysAllocString(w100);
5867     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5868     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
5869     SysFreeString(bstr);
5870
5871     IDispatchEx_Release(dispex);
5872 }
5873
5874
5875
5876 static void test_elems(IHTMLDocument2 *doc)
5877 {
5878     IHTMLElementCollection *col;
5879     IHTMLDOMChildrenCollection *child_col;
5880     IHTMLElement *elem, *elem2, *elem3;
5881     IHTMLDOMNode *node, *node2;
5882     IHTMLWindow2 *window;
5883     IDispatch *disp;
5884     LONG type;
5885     HRESULT hres;
5886     IHTMLElementCollection *collection;
5887     IHTMLDocument3 *doc3;
5888     BSTR str;
5889
5890     static const elem_type_t all_types[] = {
5891         ET_HTML,
5892         ET_HEAD,
5893         ET_TITLE,
5894         ET_STYLE,
5895         ET_META,
5896         ET_LINK,
5897         ET_BODY,
5898         ET_COMMENT,
5899         ET_A,
5900         ET_LABEL,
5901         ET_INPUT,
5902         ET_BUTTON,
5903         ET_SELECT,
5904         ET_OPTION,
5905         ET_OPTION,
5906         ET_TEXTAREA,
5907         ET_TABLE,
5908         ET_TBODY,
5909         ET_TR,
5910         ET_TR,
5911         ET_TD,
5912         ET_TD,
5913         ET_SCRIPT,
5914         ET_TEST,
5915         ET_OBJECT,
5916         ET_EMBED,
5917         ET_IMG,
5918         ET_IFRAME,
5919         ET_FORM,
5920         ET_DIV
5921     };
5922
5923     static const elem_type_t item_types[] = {
5924         ET_A,
5925         ET_OPTION,
5926         ET_TEXTAREA
5927     };
5928
5929     hres = IHTMLDocument2_get_all(doc, &col);
5930     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5931     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5932     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
5933     IHTMLElementCollection_Release(col);
5934
5935     hres = IHTMLDocument2_get_images(doc, &collection);
5936     ok(hres == S_OK, "get_images failed: %08x\n", hres);
5937     if(hres == S_OK)
5938     {
5939         static const elem_type_t images_types[] = {ET_IMG};
5940         test_elem_collection((IUnknown*)collection, images_types, 1);
5941
5942         IHTMLElementCollection_Release(collection);
5943     }
5944
5945     hres = IHTMLDocument2_get_links(doc, &collection);
5946     ok(hres == S_OK, "get_links failed: %08x\n", hres);
5947     if(hres == S_OK)
5948     {
5949         static const elem_type_t images_types[] = {ET_A};
5950         test_elem_collection((IUnknown*)collection, images_types, 1);
5951
5952         IHTMLElementCollection_Release(collection);
5953     }
5954
5955     hres = IHTMLDocument2_get_anchors(doc, &collection);
5956     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5957     if(hres == S_OK)
5958     {
5959         static const elem_type_t anchor_types[] = {ET_A};
5960         test_elem_collection((IUnknown*)collection, anchor_types, 1);
5961
5962         IHTMLElementCollection_Release(collection);
5963     }
5964
5965     test_plugins_col(doc);
5966
5967     elem = get_doc_elem(doc);
5968     test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1);
5969     IHTMLElement_Release(elem);
5970
5971     get_elem_by_id(doc, "xxx", FALSE);
5972     elem = get_doc_elem_by_id(doc, "xxx");
5973     ok(!elem, "elem != NULL\n");
5974
5975     elem = get_doc_elem_by_id(doc, "s");
5976     ok(elem != NULL, "elem == NULL\n");
5977     if(elem) {
5978         test_elem_type((IUnknown*)elem, ET_SELECT);
5979         test_elem_attr(elem, "xxx", NULL);
5980         test_elem_attr(elem, "id", "s");
5981         test_elem_class((IUnknown*)elem, NULL);
5982         test_elem_set_class((IUnknown*)elem, "cl");
5983         test_elem_set_class((IUnknown*)elem, NULL);
5984         test_elem_tabindex((IUnknown*)elem, 0);
5985         test_elem_set_tabindex((IUnknown*)elem, 1);
5986         test_elem_filters((IUnknown*)elem);
5987
5988         node = test_node_get_parent((IUnknown*)elem);
5989         ok(node != NULL, "node == NULL\n");
5990         test_node_name((IUnknown*)node, "BODY");
5991         node2 = test_node_get_parent((IUnknown*)node);
5992         IHTMLDOMNode_Release(node);
5993         ok(node2 != NULL, "node == NULL\n");
5994         test_node_name((IUnknown*)node2, "HTML");
5995         node = test_node_get_parent((IUnknown*)node2);
5996         IHTMLDOMNode_Release(node2);
5997         ok(node != NULL, "node == NULL\n");
5998         if (node)
5999         {
6000             test_node_name((IUnknown*)node, "#document");
6001             type = get_node_type((IUnknown*)node);
6002             ok(type == 9, "type=%d, expected 9\n", type);
6003             node2 = test_node_get_parent((IUnknown*)node);
6004             IHTMLDOMNode_Release(node);
6005             ok(node2 == NULL, "node != NULL\n");
6006         }
6007
6008         elem2 = test_elem_get_parent((IUnknown*)elem);
6009         ok(elem2 != NULL, "elem2 == NULL\n");
6010         test_node_name((IUnknown*)elem2, "BODY");
6011
6012         elem3 = test_elem_get_parent((IUnknown*)elem2);
6013         ok(elem3 != NULL, "elem3 == NULL\n");
6014         test_node_name((IUnknown*)elem3, "HTML");
6015
6016         test_elem_contains(elem3, elem2, VARIANT_TRUE);
6017         test_elem_contains(elem3, elem, VARIANT_TRUE);
6018         test_elem_contains(elem2, elem, VARIANT_TRUE);
6019         test_elem_contains(elem2, elem3, VARIANT_FALSE);
6020         test_elem_contains(elem, elem3, VARIANT_FALSE);
6021         test_elem_contains(elem, elem2, VARIANT_FALSE);
6022         test_elem_contains(elem, elem, VARIANT_TRUE);
6023         IHTMLElement_Release(elem2);
6024
6025         elem2 = test_elem_get_parent((IUnknown*)elem3);
6026         ok(elem2 == NULL, "elem2 != NULL\n");
6027         IHTMLElement_Release(elem3);
6028
6029         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2, NULL);
6030         test_elem_getelembytag((IUnknown*)elem, ET_SELECT, 0, NULL);
6031         test_elem_getelembytag((IUnknown*)elem, ET_HTML, 0, NULL);
6032
6033         test_elem_innertext(elem, "opt1opt2");
6034
6035         IHTMLElement_Release(elem);
6036     }
6037
6038     elem = get_elem_by_id(doc, "s", TRUE);
6039     if(elem) {
6040         IHTMLSelectElement *select = get_select_iface((IUnknown*)elem);
6041         IHTMLDocument2 *doc_node, *elem_doc;
6042
6043         test_select_elem(select);
6044
6045         test_elem_title((IUnknown*)select, NULL);
6046         test_elem_set_title((IUnknown*)select, "Title");
6047         test_elem_title((IUnknown*)select, "Title");
6048         test_elem_offset((IUnknown*)select, "BODY");
6049         test_elem_bounding_client_rect((IUnknown*)select);
6050
6051         node = get_first_child((IUnknown*)select);
6052         ok(node != NULL, "node == NULL\n");
6053         if(node) {
6054             test_elem_type((IUnknown*)node, ET_OPTION);
6055             IHTMLDOMNode_Release(node);
6056         }
6057
6058         type = get_node_type((IUnknown*)select);
6059         ok(type == 1, "type=%d\n", type);
6060
6061         IHTMLSelectElement_Release(select);
6062
6063         elem_doc = get_elem_doc((IUnknown*)elem);
6064
6065         doc_node = get_doc_node(doc);
6066         ok(iface_cmp((IUnknown*)elem_doc, (IUnknown*)doc_node), "disp != doc\n");
6067         IHTMLDocument2_Release(doc_node);
6068         IHTMLDocument2_Release(elem_doc);
6069
6070         IHTMLElement_Release(elem);
6071     }
6072
6073     elem = get_elem_by_id(doc, "sc", TRUE);
6074     if(elem) {
6075         IHTMLScriptElement *script;
6076         BSTR type;
6077
6078         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLScriptElement, (void**)&script);
6079         ok(hres == S_OK, "Could not get IHTMLScriptElement interface: %08x\n", hres);
6080
6081         if(hres == S_OK)
6082         {
6083             VARIANT_BOOL vb;
6084
6085             hres = IHTMLScriptElement_put_type (script, NULL);
6086             ok(hres == S_OK, "put_type failed: %08x\n", hres);
6087             hres = IHTMLScriptElement_get_type(script, &type);
6088             ok(hres == S_OK, "get_type failed: %08x\n", hres);
6089             ok(type == NULL, "Unexpected type %s\n", wine_dbgstr_w(type));
6090
6091             hres = IHTMLScriptElement_put_type (script, a2bstr ("text/javascript"));
6092             ok(hres == S_OK, "put_type failed: %08x\n", hres);
6093             hres = IHTMLScriptElement_get_type(script, &type);
6094             ok(hres == S_OK, "get_type failed: %08x\n", hres);
6095             ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type));
6096             SysFreeString(type);
6097
6098             test_script_text(script, "<!--\nfunction Testing() {}\n// -->\n");
6099
6100             /* test defer */
6101             hres = IHTMLScriptElement_put_defer(script, VARIANT_TRUE);
6102             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
6103
6104             hres = IHTMLScriptElement_get_defer(script, &vb);
6105             ok(hres == S_OK, "get_defer failed: %08x\n", hres);
6106             ok(vb == VARIANT_TRUE, "get_defer result is %08x\n", hres);
6107
6108             hres = IHTMLScriptElement_put_defer(script, VARIANT_FALSE);
6109             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
6110
6111             str = (BSTR)0xdeadbeef;
6112             hres = IHTMLScriptElement_get_src(script, &str);
6113             ok(hres == S_OK, "get_src failed: %08x\n", hres);
6114             ok(!str, "src = %s\n", wine_dbgstr_w(str));
6115         }
6116
6117         IHTMLScriptElement_Release(script);
6118     }
6119
6120     elem = get_elem_by_id(doc, "in", TRUE);
6121     if(elem) {
6122         IHTMLInputElement *input;
6123
6124         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLInputElement, (void**)&input);
6125         ok(hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
6126
6127         test_elem_id((IUnknown*)elem, "in");
6128         test_elem_put_id((IUnknown*)elem, "newin");
6129         test_input_get_disabled(input, VARIANT_FALSE);
6130         test_input_set_disabled(input, VARIANT_TRUE);
6131         test_input_set_disabled(input, VARIANT_FALSE);
6132         test_elem3_set_disabled((IUnknown*)input, VARIANT_TRUE);
6133         test_input_get_disabled(input, VARIANT_TRUE);
6134         test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE);
6135         test_input_get_disabled(input, VARIANT_FALSE);
6136         test_elem_client_size((IUnknown*)elem);
6137         test_input_type(input, "text");
6138
6139         test_node_get_value_str((IUnknown*)elem, NULL);
6140         test_node_put_value_str((IUnknown*)elem, "test");
6141         test_node_get_value_str((IUnknown*)elem, NULL);
6142         test_input_value((IUnknown*)elem, NULL);
6143         test_input_defaultValue((IUnknown*)elem, NULL);
6144         test_input_put_value((IUnknown*)elem, "test");
6145         test_input_defaultValue((IUnknown*)elem, NULL);
6146         test_elem_class((IUnknown*)elem, "testclass");
6147         test_elem_tabindex((IUnknown*)elem, 2);
6148         test_elem_set_tabindex((IUnknown*)elem, 3);
6149         test_elem_title((IUnknown*)elem, "test title");
6150
6151         test_input_get_defaultchecked(input, VARIANT_FALSE);
6152         test_input_set_defaultchecked(input, VARIANT_TRUE);
6153         test_input_set_defaultchecked(input, VARIANT_FALSE);
6154
6155         test_input_get_checked(input, VARIANT_FALSE);
6156         test_input_set_checked(input, VARIANT_TRUE);
6157         test_input_set_checked(input, VARIANT_FALSE);
6158
6159         test_input_maxlength(input, 0x7fffffff);
6160         test_input_set_maxlength(input, 30);
6161
6162         test_input_name(input, NULL);
6163         test_input_set_name(input, "test");
6164
6165         test_input_src(input, NULL);
6166         test_input_set_src(input, "about:blank");
6167
6168         IHTMLInputElement_Release(input);
6169         IHTMLElement_Release(elem);
6170     }
6171
6172     elem = get_elem_by_id(doc, "imgid", TRUE);
6173     if(elem) {
6174         test_img_src((IUnknown*)elem, "", NULL);
6175         test_img_set_src((IUnknown*)elem, "about:blank");
6176         test_img_src((IUnknown*)elem, "about:blank", NULL);
6177         test_img_alt((IUnknown*)elem, NULL);
6178         test_img_set_alt((IUnknown*)elem, "alt test");
6179         test_img_name((IUnknown*)elem, "WineImg");
6180         test_img_complete(elem, VARIANT_FALSE);
6181         IHTMLElement_Release(elem);
6182     }
6183
6184     elem = get_elem_by_id(doc, "attr", TRUE);
6185     if(elem) {
6186         test_dynamic_properties(elem);
6187         test_attr_collection(elem);
6188         IHTMLElement_Release(elem);
6189     }
6190
6191     elem = get_elem_by_id(doc, "styleid", TRUE);
6192     if(elem) {
6193         test_style_media((IUnknown*)elem, NULL);
6194         test_style_put_media((IUnknown*)elem, "screen");
6195         test_style_type((IUnknown*)elem, NULL);
6196         test_style_put_type((IUnknown*)elem, "text/css");
6197         IHTMLElement_Release(elem);
6198     }
6199
6200     elem = get_doc_elem_by_id(doc, "tbl");
6201     ok(elem != NULL, "elem == NULL\n");
6202     if(elem) {
6203         test_table_elem(elem);
6204         IHTMLElement_Release(elem);
6205     }
6206
6207     elem = get_doc_elem_by_id(doc, "row2");
6208     ok(elem != NULL, "elem == NULL\n");
6209     if(elem) {
6210         test_tr_elem(elem);
6211         IHTMLElement_Release(elem);
6212     }
6213
6214     elem = get_doc_elem_by_id(doc, "ifr");
6215     ok(elem != NULL, "elem == NULL\n");
6216     if(elem) {
6217         test_iframe_elem(elem);
6218         IHTMLElement_Release(elem);
6219     }
6220
6221     elem = get_doc_elem_by_id(doc, "btnid");
6222     ok(elem != NULL, "elem == NULL\n");
6223     if(elem) {
6224         test_button_elem(elem);
6225         test_button_get_disabled(elem, VARIANT_FALSE);
6226         test_button_set_disabled(elem, VARIANT_TRUE);
6227         test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
6228         test_button_get_disabled(elem, VARIANT_FALSE);
6229         IHTMLElement_Release(elem);
6230     }
6231
6232     elem = get_doc_elem_by_id(doc, "objid");
6233     ok(elem != NULL, "elem == NULL\n");
6234     if(elem) {
6235         test_object_vspace((IUnknown*)elem, 100);
6236         test_object_name(elem, "objname");
6237         set_object_name(elem, "test");
6238         set_object_name(elem, NULL);
6239         IHTMLElement_Release(elem);
6240     }
6241
6242     elem = get_elem_by_id(doc, "a", TRUE);
6243     if(elem) {
6244         test_anchor_href((IUnknown*)elem, "http://test/");
6245
6246         /* Change the href */
6247         test_anchor_put_href((IUnknown*)elem, "http://test1/");
6248         test_anchor_href((IUnknown*)elem, "http://test1/");
6249         test_anchor_hostname((IUnknown*)elem, "test1");
6250
6251         /* Restore the href */
6252         test_anchor_put_href((IUnknown*)elem, "http://test/");
6253         test_anchor_href((IUnknown*)elem, "http://test/");
6254         test_anchor_hostname((IUnknown*)elem, "test");
6255
6256         /* target */
6257         test_anchor_get_target((IUnknown*)elem, NULL);
6258
6259         /* Change the target */
6260         test_anchor_put_target((IUnknown*)elem, "wine");
6261         test_anchor_get_target((IUnknown*)elem, "wine");
6262
6263         /* Restore the target */
6264         test_anchor_put_target((IUnknown*)elem, NULL);
6265         test_anchor_get_target((IUnknown*)elem, NULL);
6266
6267         test_anchor_name((IUnknown*)elem, "x");
6268         test_anchor_put_name((IUnknown*)elem, "anchor name");
6269         test_anchor_put_name((IUnknown*)elem, NULL);
6270         test_anchor_put_name((IUnknown*)elem, "x");
6271
6272         IHTMLElement_Release(elem);
6273     }
6274
6275     elem = get_doc_elem_by_id(doc, "metaid");
6276     if(elem) {
6277         test_meta_name((IUnknown*)elem, "meta name");
6278         test_meta_content((IUnknown*)elem, "text/html; charset=utf-8");
6279         test_meta_httpequiv((IUnknown*)elem, "Content-Type");
6280         IHTMLElement_Release(elem);
6281     }
6282
6283     elem = doc_get_body(doc);
6284
6285     node = get_first_child((IUnknown*)elem);
6286     ok(node != NULL, "node == NULL\n");
6287     if(node) {
6288         test_ifaces((IUnknown*)node, text_iids);
6289         test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
6290
6291         node2 = get_first_child((IUnknown*)node);
6292         ok(!node2, "node2 != NULL\n");
6293
6294         type = get_node_type((IUnknown*)node);
6295         ok(type == 3, "type=%d\n", type);
6296
6297         test_node_get_value_str((IUnknown*)node, "text test");
6298         test_node_put_value_str((IUnknown*)elem, "test text");
6299         test_node_get_value_str((IUnknown*)node, "text test");
6300
6301         hres = IHTMLDOMNode_get_attributes(node, &disp);
6302         ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
6303         ok(!disp, "disp != NULL\n");
6304
6305         IHTMLDOMNode_Release(node);
6306     }
6307
6308     child_col = get_child_nodes((IUnknown*)elem);
6309     ok(child_col != NULL, "child_coll == NULL\n");
6310     if(child_col) {
6311         LONG length = 0;
6312
6313         test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]");
6314
6315         hres = IHTMLDOMChildrenCollection_get_length(child_col, &length);
6316         ok(hres == S_OK, "get_length failed: %08x\n", hres);
6317         ok(length, "length=0\n");
6318
6319         node2 = NULL;
6320         node = get_child_item(child_col, 0);
6321         ok(node != NULL, "node == NULL\n");
6322         if(node) {
6323             IHTMLDOMNode *prev;
6324
6325             type = get_node_type((IUnknown*)node);
6326             ok(type == 3, "type=%d\n", type);
6327             node2 = node_get_next((IUnknown*)node);
6328
6329             prev = node_get_prev((IUnknown*)node2);
6330             ok(iface_cmp((IUnknown*)node, (IUnknown*)prev), "node != prev\n");
6331             IHTMLDOMNode_Release(prev);
6332
6333             IHTMLDOMNode_Release(node);
6334         }
6335
6336         node = get_child_item(child_col, 1);
6337         ok(node != NULL, "node == NULL\n");
6338         if(node) {
6339             type = get_node_type((IUnknown*)node);
6340             ok(type == 8, "type=%d\n", type);
6341
6342             test_elem_id((IUnknown*)node, NULL);
6343             ok(iface_cmp((IUnknown*)node2, (IUnknown*)node), "node2 != node\n");
6344             IHTMLDOMNode_Release(node2);
6345             IHTMLDOMNode_Release(node);
6346         }
6347
6348         hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL);
6349         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
6350
6351         hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL);
6352         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
6353
6354         hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp);
6355         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
6356
6357         hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp);
6358         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
6359
6360         test_child_col_disp(child_col);
6361
6362         IHTMLDOMChildrenCollection_Release(child_col);
6363     }
6364
6365     test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
6366     test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
6367     test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
6368
6369     IHTMLElement_Release(elem);
6370
6371     elem = get_doc_elem_by_id(doc, "frm");
6372     ok(elem != NULL, "elem == NULL\n");
6373     if(elem) {
6374         test_form_length((IUnknown*)elem, 0);
6375         test_form_elements((IUnknown*)elem);
6376         IHTMLElement_Release(elem);
6377     }
6378
6379     test_stylesheets(doc);
6380     test_create_option_elem(doc);
6381     test_create_img_elem(doc);
6382
6383     elem = get_doc_elem_by_id(doc, "tbl");
6384     ok(elem != NULL, "elem = NULL\n");
6385     test_elem_set_innertext(elem, "inner text");
6386     IHTMLElement_Release(elem);
6387
6388     test_doc_title(doc, "test");
6389     test_doc_set_title(doc, "test title");
6390     test_doc_title(doc, "test title");
6391
6392     disp = NULL;
6393     hres = IHTMLDocument2_get_Script(doc, &disp);
6394     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
6395     if(hres == S_OK)
6396     {
6397         IDispatchEx *dispex;
6398         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
6399         ok(hres == S_OK, "IDispatch_QueryInterface failed: %08x\n", hres);
6400         if(hres == S_OK)
6401         {
6402             DISPID pid = -1;
6403             BSTR str = a2bstr("Testing");
6404             hres = IDispatchEx_GetDispID(dispex, str, 1, &pid);
6405             ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
6406             ok(pid != -1, "pid == -1\n");
6407             SysFreeString(str);
6408             IDispatchEx_Release(dispex);
6409         }
6410     }
6411     IDispatch_Release(disp);
6412
6413     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
6414     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
6415
6416     str = a2bstr("Img");
6417     hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col);
6418     ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres);
6419     SysFreeString(str);
6420     if(hres == S_OK)
6421     {
6422         static const elem_type_t img_types[] = { ET_IMG };
6423
6424         test_elem_collection((IUnknown*)col, img_types, sizeof(img_types)/sizeof(img_types[0]));
6425         IHTMLElementCollection_Release(col);
6426     }
6427
6428     elem = get_doc_elem_by_id(doc, "y");
6429     test_elem_set_innerhtml((IUnknown*)elem, "inner html");
6430     test_elem_innerhtml((IUnknown*)elem, "inner html");
6431     test_elem_set_innerhtml((IUnknown*)elem, "");
6432     test_elem_innerhtml((IUnknown*)elem, NULL);
6433     node = node_get_next((IUnknown*)elem);
6434     ok(!node, "node = %p\n", node);
6435
6436     elem2 = get_doc_elem_by_id(doc, "x");
6437     test_elem_tag((IUnknown*)elem2, "A");
6438     node = node_get_next((IUnknown*)elem2);
6439     IHTMLDOMNode_Release(node);
6440     IHTMLElement_Release(elem2);
6441     IHTMLElement_Release(elem);
6442
6443     IHTMLDocument3_Release(doc3);
6444
6445     elem = get_elem_by_id(doc, "s", TRUE);
6446     if(elem) {
6447         static const elem_type_t select_types[] = { ET_OPTION, ET_OPTION, ET_OPTION };
6448
6449         test_select_put_length((IUnknown*)elem, 3);
6450         test_elem_all((IUnknown*)elem, select_types, sizeof(select_types)/sizeof(*select_types));
6451         test_select_put_length((IUnknown*)elem, 1);
6452         test_elem_all((IUnknown*)elem, select_types, 1);
6453         IHTMLElement_Release(elem);
6454     }
6455
6456     window = get_doc_window(doc);
6457     test_window_name(window, NULL);
6458     set_window_name(window, "test name");
6459     test_window_length(window, 1);
6460     IHTMLWindow2_Release(window);
6461 }
6462
6463 static void test_attr(IHTMLElement *elem)
6464 {
6465     IHTMLDOMAttribute *attr, *attr2;
6466     VARIANT v;
6467
6468     get_elem_attr_node((IUnknown*)elem, "noattr", FALSE);
6469
6470     attr = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
6471
6472     test_disp((IUnknown*)attr, &DIID_DispHTMLDOMAttribute, "[object]");
6473     test_ifaces((IUnknown*)attr, attr_iids);
6474     test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
6475     test_attr_specified(attr, VARIANT_TRUE);
6476
6477     attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
6478     ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");
6479     IHTMLDOMAttribute_Release(attr2);
6480
6481     get_attr_node_value(attr, &v, VT_BSTR);
6482     ok(!strcmp_wa(V_BSTR(&v), "divid"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
6483     VariantClear(&v);
6484
6485     IHTMLDOMAttribute_Release(attr);
6486
6487     attr = get_elem_attr_node((IUnknown*)elem, "emptyattr", TRUE);
6488     get_attr_node_value(attr, &v, VT_BSTR);
6489     ok(!V_BSTR(&v), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
6490     VariantClear(&v);
6491     test_attr_specified(attr, VARIANT_TRUE);
6492     IHTMLDOMAttribute_Release(attr);
6493
6494     V_VT(&v) = VT_I4;
6495     V_I4(&v) = 100;
6496     set_dispex_value((IUnknown*)elem, "dispprop", &v);
6497     attr = get_elem_attr_node((IUnknown*)elem, "dispprop", TRUE);
6498     get_attr_node_value(attr, &v, VT_I4);
6499     ok(V_I4(&v) == 100, "V_I4(v) = %d\n", V_I4(&v));
6500     test_attr_specified(attr, VARIANT_TRUE);
6501     IHTMLDOMAttribute_Release(attr);
6502
6503     attr = get_elem_attr_node((IUnknown*)elem, "tabIndex", TRUE);
6504     test_attr_specified(attr, VARIANT_FALSE);
6505     IHTMLDOMAttribute_Release(attr);
6506 }
6507
6508 static void test_blocked(IHTMLDocument2 *doc, IHTMLElement *outer_elem)
6509 {
6510     IHTMLElement *elem;
6511
6512     test_elem_set_innerhtml((IUnknown*)outer_elem,
6513             "<img id=\"imgid\" src=\"BLOCKED::http://www.winehq.org/img.png\" />");
6514     elem = get_elem_by_id(doc, "imgid", TRUE);
6515     if(elem) {
6516         test_img_src((IUnknown*)elem, "BLOCKED::", "blocked::http://www.winehq.org/img.png");
6517         IHTMLElement_Release(elem);
6518     }
6519
6520     test_elem_set_innerhtml((IUnknown*)outer_elem,
6521             "<img id=\"imgid\" src=\"BLOCKE::http://www.winehq.org/img.png\" />");
6522     elem = get_elem_by_id(doc, "imgid", TRUE);
6523     if(elem) {
6524         test_img_src((IUnknown*)elem, "blocke::http://www.winehq.org/img.png", NULL);
6525         test_img_set_src((IUnknown*)elem, "BLOCKED:http://www.winehq.org/img.png");
6526         test_img_src((IUnknown*)elem, "blocked:http://www.winehq.org/img.png", NULL);
6527         test_img_set_src((IUnknown*)elem, "blocked::http://www.winehq.org/img.png");
6528         test_img_src((IUnknown*)elem, "BLOCKED::", "blocked::http://www.winehq.org/img.png");
6529         IHTMLElement_Release(elem);
6530     }
6531 }
6532
6533 static void test_elems2(IHTMLDocument2 *doc)
6534 {
6535     IHTMLElement *elem, *elem2, *div;
6536
6537     static const elem_type_t outer_types[] = {
6538         ET_BR,
6539         ET_A
6540     };
6541
6542     div = get_doc_elem_by_id(doc, "divid");
6543
6544     elem = get_elem_by_id(doc, "linkid", TRUE);
6545     if(elem) {
6546         test_link_disabled(elem, VARIANT_FALSE);
6547         test_link_rel(elem, "stylesheet");
6548         test_link_type(elem, "text/css");
6549         test_link_href(elem, "about:blank");
6550         link_put_disabled(elem, VARIANT_TRUE);
6551         link_put_rel(elem, "prev");
6552         link_put_type(elem, "text/plain");
6553         link_put_href(elem, "about:prev");
6554         IHTMLElement_Release(elem);
6555     }
6556
6557     test_elem_set_innerhtml((IUnknown*)div, "<div id=\"innerid\"></div>");
6558     elem2 = get_doc_elem_by_id(doc, "innerid");
6559     ok(elem2 != NULL, "elem2 == NULL\n");
6560     test_elem_set_outerhtml((IUnknown*)elem2, "<br><a href=\"about:blank\" id=\"aid\">a</a>");
6561     test_elem_all((IUnknown*)div, outer_types, sizeof(outer_types)/sizeof(*outer_types));
6562     IHTMLElement_Release(elem2);
6563
6564     elem2 = get_doc_elem_by_id(doc, "aid");
6565     ok(elem2 != NULL, "elem2 == NULL\n");
6566     test_elem_set_outerhtml((IUnknown*)elem2, "");
6567     test_elem_all((IUnknown*)div, outer_types, 1);
6568     IHTMLElement_Release(elem2);
6569
6570     test_elem_set_innerhtml((IUnknown*)div, "<textarea id=\"ta\"></textarea>");
6571     elem = get_elem_by_id(doc, "ta", TRUE);
6572     if(elem) {
6573         test_textarea_value((IUnknown*)elem, NULL);
6574         test_textarea_put_value((IUnknown*)elem, "test");
6575         test_textarea_readonly((IUnknown*)elem, VARIANT_FALSE);
6576         test_textarea_put_readonly((IUnknown*)elem, VARIANT_TRUE);
6577         test_textarea_put_readonly((IUnknown*)elem, VARIANT_FALSE);
6578         test_textarea_type((IUnknown*)elem);
6579         IHTMLElement_Release(elem);
6580     }
6581
6582     test_elem_set_innerhtml((IUnknown*)div,
6583             "<input value=\"val\" id =\"inputid\"  />");
6584     elem = get_elem_by_id(doc, "inputid", TRUE);
6585     if(elem) {
6586         test_input_defaultValue((IUnknown*)elem, "val");
6587         test_input_put_value((IUnknown*)elem, "test");
6588         test_input_put_defaultValue((IUnknown*)elem, "new val");
6589         test_input_value((IUnknown*)elem, "test");
6590         IHTMLElement_Release(elem);
6591     }
6592
6593     test_elem_set_innerhtml((IUnknown*)div, "");
6594     test_insert_adjacent_elems(doc, div);
6595
6596     test_elem_set_innerhtml((IUnknown*)div,
6597             "<form id=\"form\"><input type=\"button\" /><div><input type=\"text\" /></div></textarea>");
6598     elem = get_elem_by_id(doc, "form", TRUE);
6599     if(elem) {
6600         test_form_length((IUnknown*)elem, 2);
6601         test_form_item(elem);
6602         test_form_action((IUnknown*)elem, NULL);
6603         test_form_put_action((IUnknown*)elem, "about:blank");
6604         test_form_method((IUnknown*)elem, "get");
6605         test_form_put_method((IUnknown*)elem, S_OK, "post");
6606         test_form_put_method((IUnknown*)elem, E_INVALIDARG, "put");
6607         test_form_method((IUnknown*)elem, "post");
6608         test_form_name((IUnknown*)elem, NULL);
6609         test_form_put_name((IUnknown*)elem, "Name");
6610         test_form_encoding((IUnknown*)elem, "application/x-www-form-urlencoded");
6611         test_form_put_encoding((IUnknown*)elem, S_OK, "text/plain");
6612         test_form_put_encoding((IUnknown*)elem, S_OK, "multipart/form-data");
6613         test_form_put_encoding((IUnknown*)elem, E_INVALIDARG, "image/png");
6614         test_form_encoding((IUnknown*)elem, "multipart/form-data");
6615         test_form_elements((IUnknown*)elem);
6616         IHTMLElement_Release(elem);
6617     }
6618
6619     test_attr(div);
6620     test_blocked(doc, div);
6621
6622     IHTMLElement_Release(div);
6623 }
6624
6625 static void test_create_elems(IHTMLDocument2 *doc)
6626 {
6627     IHTMLElement *elem, *body, *elem2;
6628     IHTMLDOMNode *node, *node2, *node3, *comment;
6629     IHTMLDOMAttribute *attr;
6630     IHTMLDocument5 *doc5;
6631     IDispatch *disp;
6632     VARIANT var;
6633     LONG type;
6634     HRESULT hres;
6635     BSTR str;
6636
6637     static const elem_type_t types1[] = { ET_TESTG };
6638
6639     elem = test_create_elem(doc, "TEST");
6640     test_elem_tag((IUnknown*)elem, "TEST");
6641     type = get_node_type((IUnknown*)elem);
6642     ok(type == 1, "type=%d\n", type);
6643     test_ifaces((IUnknown*)elem, elem_iids);
6644     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
6645
6646     body = doc_get_body(doc);
6647     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
6648
6649     node = test_node_append_child((IUnknown*)body, (IUnknown*)elem);
6650     test_node_has_child((IUnknown*)body, VARIANT_TRUE);
6651     elem2 = get_elem_iface((IUnknown*)node);
6652     IHTMLElement_Release(elem2);
6653
6654     hres = IHTMLElement_get_all(body, &disp);
6655     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6656     test_elem_collection((IUnknown*)disp, types1, sizeof(types1)/sizeof(types1[0]));
6657     IDispatch_Release(disp);
6658
6659     test_node_remove_child((IUnknown*)body, node);
6660
6661     hres = IHTMLElement_get_all(body, &disp);
6662     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6663     test_elem_collection((IUnknown*)disp, NULL, 0);
6664     IDispatch_Release(disp);
6665     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
6666
6667     IHTMLElement_Release(elem);
6668     IHTMLDOMNode_Release(node);
6669
6670     node = test_create_text(doc, "abc");
6671     test_ifaces((IUnknown*)node, text_iids);
6672     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
6673     test_text_length((IUnknown*)node, 3);
6674     test_text_data((IUnknown*)node, "abc");
6675     set_text_data((IUnknown*)node, "test");
6676     test_text_data((IUnknown*)node, "test");
6677
6678     V_VT(&var) = VT_NULL;
6679     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
6680     IHTMLDOMNode_Release(node);
6681
6682     node = test_create_text(doc, "insert ");
6683
6684     V_VT(&var) = VT_DISPATCH;
6685     V_DISPATCH(&var) = (IDispatch*)node2;
6686     node3 = test_node_insertbefore((IUnknown*)body, node, &var);
6687     IHTMLDOMNode_Release(node);
6688     IHTMLDOMNode_Release(node2);
6689     IHTMLDOMNode_Release(node3);
6690
6691     test_elem_innertext(body, "insert test");
6692     test_elem_innerhtml((IUnknown*)body, "insert test");
6693
6694     node = test_create_text(doc, " Test");
6695     V_VT(&var) = VT_DISPATCH;
6696     V_DISPATCH(&var) = NULL;
6697     test_node_insertbefore((IUnknown*)body, node, &var);
6698     test_elem_innertext(body, "insert test Test");
6699     IHTMLDOMNode_Release(node);
6700
6701     doc5 = get_htmldoc5_iface((IUnknown*)doc);
6702     if(doc5) {
6703         str = a2bstr("testing");
6704         hres = IHTMLDocument5_createComment(doc5, str, &comment);
6705         SysFreeString(str);
6706         ok(hres == S_OK, "createComment failed: %08x\n", hres);
6707         if(hres == S_OK)
6708         {
6709             type = get_node_type((IUnknown*)comment);
6710             ok(type == 8, "type=%d, expected 8\n", type);
6711
6712             test_node_get_value_str((IUnknown*)comment, "testing");
6713             test_elem_title((IUnknown*)comment, NULL);
6714             test_elem_set_title((IUnknown*)comment, "comment title");
6715             test_elem_title((IUnknown*)comment, "comment title");
6716             test_comment_text((IUnknown*)comment, "<!--testing-->");
6717             test_elem_outerhtml((IUnknown*)comment, "<!--testing-->");
6718             test_comment_attrs((IUnknown*)comment);
6719
6720             IHTMLDOMNode_Release(comment);
6721         }
6722
6723         str = a2bstr("Test");
6724         hres = IHTMLDocument5_createAttribute(doc5, str, &attr);
6725         ok(hres == S_OK, "createAttribute dailed: %08x\n", hres);
6726         SysFreeString(str);
6727         if(SUCCEEDED(hres)) {
6728             test_disp((IUnknown*)attr, &DIID_DispHTMLDOMAttribute, "[object]");
6729             test_ifaces((IUnknown*)attr, attr_iids);
6730             test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
6731
6732             test_attr_node_name(attr, "Test");
6733
6734             IHTMLDOMAttribute_Release(attr);
6735         }
6736
6737         IHTMLDocument5_Release(doc5);
6738     }
6739
6740     IHTMLElement_Release(body);
6741 }
6742
6743 static void test_replacechild_elems(IHTMLDocument2 *doc)
6744 {
6745     IHTMLElement *body;
6746     IHTMLDOMNode *node, *node2, *node3;
6747     IHTMLDOMNode *nodeBody, *nodeNew;
6748     HRESULT hres;
6749     VARIANT var;
6750
6751     body = doc_get_body(doc);
6752
6753     node = test_create_text(doc, "insert");
6754
6755     V_VT(&var) = VT_NULL;
6756     V_DISPATCH(&var) = NULL;
6757     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
6758     IHTMLDOMNode_Release(node);
6759
6760     test_elem_innertext(body, "insert");
6761
6762     node3 = test_create_text(doc, "replaced");
6763
6764     nodeBody = _get_node_iface(__LINE__, (IUnknown *)body);
6765
6766     hres = IHTMLDOMNode_replaceChild(nodeBody, node3, node2, &nodeNew);
6767     ok(hres == S_OK, "Expected S_OK, got 0x%08x\n", hres);
6768
6769     test_elem_innertext(body, "replaced");
6770
6771     IHTMLDOMNode_Release(node2);
6772     IHTMLDOMNode_Release(node3);
6773     IHTMLDOMNode_Release(nodeBody);
6774
6775     IHTMLElement_Release(body);
6776 }
6777
6778 static void test_noscript(IHTMLDocument2 *doc)
6779 {
6780     IHTMLElementCollection *col;
6781     IHTMLElement *body;
6782     HRESULT hres;
6783
6784     static const elem_type_t all_types[] = {
6785         ET_HTML,
6786         ET_HEAD,
6787         ET_TITLE,
6788         ET_NOSCRIPT,
6789         ET_BODY,
6790         ET_NOSCRIPT
6791     };
6792
6793     static const elem_type_t body_all_types[] = {
6794         ET_DIV,
6795         ET_NOSCRIPT
6796     };
6797
6798     hres = IHTMLDocument2_get_all(doc, &col);
6799     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6800     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6801     IHTMLElementCollection_Release(col);
6802
6803     body = doc_get_body(doc);
6804     test_elem_set_innerhtml((IUnknown*)body, "<div>test</div><noscript><a href=\"about:blank\">A</a></noscript>");
6805     test_elem_all((IUnknown*)body, body_all_types, sizeof(body_all_types)/sizeof(*body_all_types));
6806     IHTMLElement_Release(body);
6807 }
6808
6809 static void test_doctype(IHTMLDocument2 *doc)
6810 {
6811     IHTMLDocument2 *doc_node;
6812     IHTMLDOMNode *doctype;
6813     int type;
6814
6815     doc_node = get_doc_node(doc);
6816     doctype = get_first_child((IUnknown*)doc_node);
6817     IHTMLDocument2_Release(doc_node);
6818
6819     type = get_node_type((IUnknown*)doctype);
6820     ok(type == 8, "type = %d\n", type);
6821
6822     test_comment_text((IUnknown*)doctype, "<!DOCTYPE html>");
6823     test_elem_type((IUnknown*)doctype, ET_COMMENT);
6824     IHTMLDOMNode_Release(doctype);
6825 }
6826
6827 static void test_null_write(IHTMLDocument2 *doc)
6828 {
6829     HRESULT hres;
6830
6831     doc_write(doc, FALSE, NULL);
6832     doc_write(doc, TRUE, NULL);
6833
6834     hres = IHTMLDocument2_write(doc, NULL);
6835     ok(hres == S_OK,
6836        "Expected IHTMLDocument2::write to return S_OK, got 0x%08x\n", hres);
6837
6838     hres = IHTMLDocument2_writeln(doc, NULL);
6839     ok(hres == S_OK,
6840        "Expected IHTMLDocument2::writeln to return S_OK, got 0x%08x\n", hres);
6841 }
6842
6843 static void test_create_stylesheet(IHTMLDocument2 *doc)
6844 {
6845     IHTMLStyleSheet *stylesheet, *stylesheet2;
6846     IHTMLStyleElement *style_elem;
6847     IHTMLElement *doc_elem, *elem;
6848     HRESULT hres;
6849
6850     static const elem_type_t all_types[] = {
6851         ET_HTML,
6852         ET_HEAD,
6853         ET_TITLE,
6854         ET_BODY,
6855         ET_DIV
6856     };
6857
6858     static const elem_type_t all_types2[] = {
6859         ET_HTML,
6860         ET_HEAD,
6861         ET_TITLE,
6862         ET_STYLE,
6863         ET_BODY,
6864         ET_DIV
6865     };
6866
6867     test_doc_all(doc, all_types, sizeof(all_types)/sizeof(*all_types));
6868
6869     hres = IHTMLDocument2_createStyleSheet(doc, NULL, -1, &stylesheet);
6870     ok(hres == S_OK, "createStyleSheet failed: %08x\n", hres);
6871
6872     test_doc_all(doc, all_types2, sizeof(all_types2)/sizeof(*all_types2));
6873
6874     doc_elem = get_doc_elem(doc);
6875
6876     test_elem_getelembytag((IUnknown*)doc_elem, ET_STYLE, 1, &elem);
6877     IHTMLElement_Release(doc_elem);
6878
6879     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLStyleElement, (void**)&style_elem);
6880     IHTMLElement_Release(elem);
6881     ok(hres == S_OK, "Could not get IHTMLStyleElement iface: %08x\n", hres);
6882
6883     stylesheet2 = NULL;
6884     hres = IHTMLStyleElement_get_styleSheet(style_elem, &stylesheet2);
6885     ok(hres == S_OK, "get_styleSheet failed: %08x\n", hres);
6886     ok(stylesheet2 != NULL, "stylesheet2 == NULL\n");
6887     ok(iface_cmp((IUnknown*)stylesheet, (IUnknown*)stylesheet2), "stylesheet != stylesheet2\n");
6888
6889     IHTMLStyleSheet_Release(stylesheet2);
6890     IHTMLStyleSheet_Release(stylesheet);
6891
6892     IHTMLStyleElement_Release(style_elem);
6893 }
6894
6895 static void test_exec(IUnknown *unk, const GUID *grpid, DWORD cmdid, VARIANT *in, VARIANT *out)
6896 {
6897     IOleCommandTarget *cmdtrg;
6898     HRESULT hres;
6899
6900     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
6901     ok(hres == S_OK, "Could not get IOleCommandTarget interface: %08x\n", hres);
6902
6903     hres = IOleCommandTarget_Exec(cmdtrg, grpid, cmdid, 0, in, out);
6904     ok(hres == S_OK, "Exec failed: %08x\n", hres);
6905
6906     IOleCommandTarget_Release(cmdtrg);
6907 }
6908
6909 static void test_indent(IHTMLDocument2 *doc)
6910 {
6911     IHTMLElementCollection *col;
6912     IHTMLTxtRange *range;
6913     HRESULT hres;
6914
6915     static const elem_type_t all_types[] = {
6916         ET_HTML,
6917         ET_HEAD,
6918         ET_TITLE,
6919         ET_BODY,
6920         ET_BR,
6921         ET_A,
6922     };
6923
6924     static const elem_type_t indent_types[] = {
6925         ET_HTML,
6926         ET_HEAD,
6927         ET_TITLE,
6928         ET_BODY,
6929         ET_BLOCKQUOTE,
6930         ET_P,
6931         ET_BR,
6932         ET_A,
6933     };
6934
6935     hres = IHTMLDocument2_get_all(doc, &col);
6936     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6937     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6938     IHTMLElementCollection_Release(col);
6939
6940     range = test_create_body_range(doc);
6941     test_exec((IUnknown*)range, &CGID_MSHTML, IDM_INDENT, NULL, NULL);
6942     IHTMLTxtRange_Release(range);
6943
6944     hres = IHTMLDocument2_get_all(doc, &col);
6945     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6946     test_elem_collection((IUnknown*)col, indent_types, sizeof(indent_types)/sizeof(indent_types[0]));
6947     IHTMLElementCollection_Release(col);
6948 }
6949
6950 static void test_cond_comment(IHTMLDocument2 *doc)
6951 {
6952     IHTMLElementCollection *col;
6953     HRESULT hres;
6954
6955     static const elem_type_t all_types[] = {
6956         ET_HTML,
6957         ET_HEAD,
6958         ET_TITLE,
6959         ET_BODY,
6960         ET_BR
6961     };
6962
6963     hres = IHTMLDocument2_get_all(doc, &col);
6964     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6965     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6966     IHTMLElementCollection_Release(col);
6967 }
6968
6969 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
6970 {
6971     ok(IsEqualGUID(riid, &IID_IServiceProvider), "riid = %s\n", dbgstr_guid(riid));
6972     return E_NOINTERFACE;
6973 }
6974
6975 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
6976 {
6977     return 2;
6978 }
6979
6980 static ULONG WINAPI Unknown_Release(IUnknown *iface)
6981 {
6982     return 1;
6983 }
6984
6985 static const IUnknownVtbl UnknownVtbl = {
6986     Unknown_QueryInterface,
6987     Unknown_AddRef,
6988     Unknown_Release,
6989 };
6990 static IUnknown obj_ident_test = { &UnknownVtbl };
6991
6992 static void test_frame(IDispatch *disp, const char *exp_id)
6993 {
6994     IHTMLWindow2 *frame2, *parent, *top;
6995     IHTMLDocument2 *parent_doc, *top_doc;
6996     IHTMLWindow4 *frame;
6997     IHTMLFrameBase *frame_elem;
6998     IObjectIdentity *obj_ident;
6999     ITravelLogClient *tlc;
7000     HRESULT hres;
7001
7002     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame);
7003     ok(hres == S_OK, "Could not get IHTMLWindow4 interface: 0x%08x\n", hres);
7004     if(FAILED(hres))
7005         return;
7006
7007     hres = IHTMLWindow4_get_frameElement(frame, &frame_elem);
7008     ok(hres == S_OK, "IHTMLWindow4_get_frameElement failed: 0x%08x\n", hres);
7009     IHTMLWindow4_Release(frame);
7010     if(FAILED(hres))
7011         return;
7012
7013     test_elem_type((IUnknown*)frame_elem, ET_FRAME);
7014     test_frame_doc((IUnknown*)frame_elem, FALSE);
7015     test_elem_id((IUnknown*)frame_elem, exp_id);
7016     IHTMLFrameBase_Release(frame_elem);
7017
7018     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow2, (void**)&frame2);
7019     ok(hres == S_OK, "Could not get IHTMLWindow2 interface: 0x%08x\n", hres);
7020     if(FAILED(hres))
7021         return;
7022
7023     hres = IHTMLWindow2_get_parent(frame2, &parent);
7024     ok(hres == S_OK, "IHTMLWindow2_get_parent failed: 0x%08x\n", hres);
7025     if(FAILED(hres)){
7026         IHTMLWindow2_Release(frame2);
7027         return;
7028     }
7029
7030     hres = IHTMLWindow2_QueryInterface(frame2, &IID_IObjectIdentity, (void**)&obj_ident);
7031     ok(hres == S_OK, "Could not get IObjectIdentity interface: %08x\n", hres);
7032     hres = IHTMLWindow2_QueryInterface(frame2, &IID_ITravelLogClient, (void**)&tlc);
7033     if(hres == E_NOINTERFACE) {
7034         win_skip("IID_ITravelLogClient not available\n");
7035         tlc = NULL;
7036     }else {
7037         ok(hres == S_OK, "Could not get ITravelLogClient interface: %08x\n", hres);
7038
7039         hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)tlc);
7040         ok(hres == S_OK, "IsEqualObject returned: 0x%08x\n", hres);
7041         ITravelLogClient_Release(tlc);
7042     }
7043
7044     hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)obj_ident);
7045     ok(hres == S_OK, "IsEqualObject returned: 0x%08x\n", hres);
7046     hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)parent);
7047     ok(hres == S_FALSE, "IsEqualObject returned: 0x%08x\n", hres);
7048     hres = IObjectIdentity_IsEqualObject(obj_ident, &obj_ident_test);
7049     ok(hres == E_NOINTERFACE, "IsEqualObject returned: 0x%08x\n", hres);
7050
7051     IObjectIdentity_Release(obj_ident);
7052
7053     hres = IHTMLWindow2_get_document(parent, &parent_doc);
7054     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
7055     IHTMLWindow2_Release(parent);
7056     if(FAILED(hres)){
7057         IHTMLWindow2_Release(frame2);
7058         return;
7059     }
7060
7061     test_doc_title(parent_doc, "frameset test");
7062     IHTMLDocument2_Release(parent_doc);
7063
7064     /* test get_top */
7065     hres = IHTMLWindow2_get_top(frame2, &top);
7066     ok(hres == S_OK, "IHTMLWindow2_get_top failed: 0x%08x\n", hres);
7067     IHTMLWindow2_Release(frame2);
7068     if(FAILED(hres))
7069         return;
7070
7071     hres = IHTMLWindow2_get_document(top, &top_doc);
7072     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
7073     IHTMLWindow2_Release(top);
7074     if(FAILED(hres))
7075         return;
7076
7077     test_doc_title(top_doc, "frameset test");
7078     IHTMLDocument2_Release(top_doc);
7079 }
7080
7081 static void test_frames_collection(IHTMLFramesCollection2 *frames, const char *frid)
7082 {
7083     VARIANT index_var, result_var;
7084     LONG length;
7085     HRESULT hres;
7086
7087     /* test result length */
7088     hres = IHTMLFramesCollection2_get_length(frames, &length);
7089     ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres);
7090     ok(length == 3, "IHTMLFramesCollection2_get_length should have been 3, was: %d\n", length);
7091
7092     /* test first frame */
7093     V_VT(&index_var) = VT_I4;
7094     V_I4(&index_var) = 0;
7095     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
7096     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
7097     if(SUCCEEDED(hres)) {
7098         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
7099         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
7100     }
7101     VariantClear(&result_var);
7102
7103     /* test second frame */
7104     V_I4(&index_var) = 1;
7105     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
7106     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
7107     if(SUCCEEDED(hres)) {
7108         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
7109         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
7110     }
7111     VariantClear(&result_var);
7112
7113     /* fail on next frame */
7114     V_I4(&index_var) = 3;
7115     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
7116     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have"
7117            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
7118     VariantClear(&result_var);
7119
7120     /* string argument (element id lookup) */
7121     V_VT(&index_var) = VT_BSTR;
7122     V_BSTR(&index_var) = a2bstr(frid);
7123     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
7124     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
7125     if(SUCCEEDED(hres)) {
7126         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
7127         test_frame(V_DISPATCH(&result_var), frid);
7128     }
7129     VariantClear(&result_var);
7130     VariantClear(&index_var);
7131
7132     /* invalid argument */
7133     V_VT(&index_var) = VT_BOOL;
7134     V_BOOL(&index_var) = VARIANT_TRUE;
7135     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
7136     ok(hres == E_INVALIDARG, "IHTMLFramesCollection2_item should have"
7137            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
7138     VariantClear(&result_var);
7139 }
7140
7141 static void test_frameset(IHTMLDocument2 *doc)
7142 {
7143     IHTMLWindow2 *window;
7144     IHTMLFramesCollection2 *frames;
7145     IHTMLElement *elem;
7146     HRESULT hres;
7147
7148     window = get_doc_window(doc);
7149
7150     /* test using IHTMLFramesCollection object */
7151
7152     hres = IHTMLWindow2_get_frames(window, &frames);
7153     ok(hres == S_OK, "IHTMLWindow2_get_frames failed: 0x%08x\n", hres);
7154     if(FAILED(hres))
7155         return;
7156
7157     test_frames_collection(frames, "fr1");
7158     IHTMLFramesCollection2_Release(frames);
7159
7160     hres = IHTMLDocument2_get_frames(doc, &frames);
7161     ok(hres == S_OK, "IHTMLDocument2_get_frames failed: 0x%08x\n", hres);
7162     if(FAILED(hres))
7163         return;
7164
7165     test_frames_collection(frames, "fr1");
7166     IHTMLFramesCollection2_Release(frames);
7167
7168     /* test using IHTMLWindow2 inheritance */
7169     test_frames_collection((IHTMLFramesCollection2*)window, "fr2");
7170
7171     /* getElementById with node name attributes */
7172     elem = get_doc_elem_by_id(doc, "nm1");
7173     test_elem_id((IUnknown*)elem, "fr1");
7174
7175     test_framebase((IUnknown*)elem);
7176     test_framebase_name(elem, "nm1");
7177     test_framebase_put_name(elem, "frame name");
7178     test_framebase_put_name(elem, NULL);
7179     test_framebase_put_name(elem, "nm1");
7180     IHTMLElement_Release(elem);
7181
7182     /* get_name with no name attr */
7183     elem = get_doc_elem_by_id(doc, "fr3");
7184     test_framebase_name(elem, NULL);
7185     test_framebase_put_name(elem, "frame name");
7186     test_framebase_put_name(elem, NULL);
7187     IHTMLElement_Release(elem);
7188
7189     IHTMLWindow2_Release(window);
7190 }
7191
7192 static IHTMLDocument2 *create_docfrag(IHTMLDocument2 *doc)
7193 {
7194     IHTMLDocument2 *frag;
7195     IHTMLDocument3 *doc3;
7196     HRESULT hres;
7197
7198     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
7199     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
7200
7201     hres = IHTMLDocument3_createDocumentFragment(doc3, &frag);
7202     IHTMLDocument3_Release(doc3);
7203     ok(hres == S_OK, "createDocumentFragment failed: %08x\n", hres);
7204     ok(frag != NULL, "frag == NULL\n");
7205
7206     return frag;
7207 }
7208
7209 static void test_docfrag(IHTMLDocument2 *doc)
7210 {
7211     IHTMLDocument2 *frag, *owner_doc, *doc_node;
7212     IHTMLElement *div, *body, *br;
7213     IHTMLElementCollection *col;
7214     IHTMLLocation *location;
7215     HRESULT hres;
7216
7217     static const elem_type_t all_types[] = {
7218         ET_HTML,
7219         ET_HEAD,
7220         ET_TITLE,
7221         ET_BODY,
7222         ET_DIV,
7223         ET_BR
7224     };
7225
7226     frag = create_docfrag(doc);
7227
7228     test_disp((IUnknown*)frag, &DIID_DispHTMLDocument, "[object]");
7229
7230     body = (void*)0xdeadbeef;
7231     hres = IHTMLDocument2_get_body(frag, &body);
7232     ok(hres == S_OK, "get_body failed: %08x\n", hres);
7233     ok(!body, "body != NULL\n");
7234
7235     location = (void*)0xdeadbeef;
7236     hres = IHTMLDocument2_get_location(frag, &location);
7237     ok(hres == E_UNEXPECTED, "get_location failed: %08x\n", hres);
7238     ok(location == (void*)0xdeadbeef, "location changed\n");
7239
7240     br = test_create_elem(doc, "BR");
7241     test_node_append_child((IUnknown*)frag, (IUnknown*)br);
7242     IHTMLElement_Release(br);
7243
7244     div = get_elem_by_id(doc, "divid", TRUE);
7245     test_node_append_child((IUnknown*)div, (IUnknown*)frag);
7246     IHTMLElement_Release(div);
7247
7248     hres = IHTMLDocument2_get_all(doc, &col);
7249     ok(hres == S_OK, "get_all failed: %08x\n", hres);
7250     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
7251     IHTMLElementCollection_Release(col);
7252
7253     div = test_create_elem(frag, "div");
7254     owner_doc = get_owner_doc((IUnknown*)div);
7255     doc_node = get_doc_node(doc);
7256     ok(iface_cmp((IUnknown*)owner_doc, (IUnknown*)doc_node), "owner_doc != doc_node\n");
7257     IHTMLDocument2_Release(doc_node);
7258     IHTMLDocument2_Release(owner_doc);
7259     IHTMLElement_Release(div);
7260
7261     IHTMLDocument2_Release(frag);
7262 }
7263
7264 static void check_quirks_mode(IHTMLDocument2 *doc)
7265 {
7266     test_compatmode(doc, "BackCompat");
7267 }
7268
7269 static void check_strict_mode(IHTMLDocument2 *doc)
7270 {
7271     test_compatmode(doc, "CSS1Compat");
7272 }
7273
7274 static IHTMLDocument2 *notif_doc;
7275 static BOOL doc_complete;
7276
7277 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
7278         REFIID riid, void**ppv)
7279 {
7280     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
7281         *ppv = iface;
7282         return S_OK;
7283     }
7284
7285     ok(0, "unexpected call\n");
7286     return E_NOINTERFACE;
7287 }
7288
7289 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
7290 {
7291     return 2;
7292 }
7293
7294 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
7295 {
7296     return 1;
7297 }
7298
7299 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
7300 {
7301     if(dispID == DISPID_READYSTATE){
7302         BSTR state;
7303         HRESULT hres;
7304
7305         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
7306         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
7307
7308         if(!strcmp_wa(state, "complete"))
7309             doc_complete = TRUE;
7310
7311         SysFreeString(state);
7312     }
7313
7314     return S_OK;
7315 }
7316
7317 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
7318 {
7319     ok(0, "unexpected call\n");
7320     return E_NOTIMPL;
7321 }
7322
7323 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
7324     PropertyNotifySink_QueryInterface,
7325     PropertyNotifySink_AddRef,
7326     PropertyNotifySink_Release,
7327     PropertyNotifySink_OnChanged,
7328     PropertyNotifySink_OnRequestEdit
7329 };
7330
7331 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
7332
7333 static IHTMLDocument2 *create_doc_with_string(const char *str)
7334 {
7335     IPersistStreamInit *init;
7336     IStream *stream;
7337     IHTMLDocument2 *doc;
7338     HGLOBAL mem;
7339     SIZE_T len;
7340
7341     notif_doc = doc = create_document();
7342     if(!doc)
7343         return NULL;
7344
7345     doc_complete = FALSE;
7346     len = strlen(str);
7347     mem = GlobalAlloc(0, len);
7348     memcpy(mem, str, len);
7349     CreateStreamOnHGlobal(mem, TRUE, &stream);
7350
7351     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
7352
7353     IPersistStreamInit_Load(init, stream);
7354     IPersistStreamInit_Release(init);
7355     IStream_Release(stream);
7356
7357     return doc;
7358 }
7359
7360 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
7361 {
7362     IConnectionPointContainer *container;
7363     IConnectionPoint *cp;
7364     DWORD cookie;
7365     HRESULT hres;
7366
7367     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
7368     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
7369
7370     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
7371     IConnectionPointContainer_Release(container);
7372     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
7373
7374     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
7375     IConnectionPoint_Release(cp);
7376     ok(hres == S_OK, "Advise failed: %08x\n", hres);
7377 }
7378
7379 typedef void (*domtest_t)(IHTMLDocument2*);
7380
7381 static void run_domtest(const char *str, domtest_t test)
7382 {
7383     IHTMLDocument2 *doc;
7384     ULONG ref;
7385     MSG msg;
7386
7387     doc = create_doc_with_string(str);
7388     if(!doc)
7389         return;
7390
7391     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
7392
7393     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
7394         TranslateMessage(&msg);
7395         DispatchMessage(&msg);
7396     }
7397
7398     test(doc);
7399
7400     ref = IHTMLDocument2_Release(doc);
7401     ok(!ref || broken(ref == 1), /* Vista */
7402        "ref = %d\n", ref);
7403 }
7404
7405 static void test_quirks_mode(void)
7406 {
7407     run_domtest("<html></html>", check_quirks_mode);
7408     run_domtest("<!DOCTYPE html>\n<html></html>", check_strict_mode);
7409 }
7410
7411 START_TEST(dom)
7412 {
7413     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
7414     pLCIDToLocaleName = (void*)GetProcAddress(hkernel32, "LCIDToLocaleName");
7415     pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
7416
7417     CoInitialize(NULL);
7418
7419     run_domtest(doc_str1, test_doc_elem);
7420     run_domtest(doc_str1, test_get_set_attr);
7421     run_domtest(range_test_str, test_txtrange);
7422     run_domtest(range_test2_str, test_txtrange2);
7423     if (winetest_interactive || ! is_ie_hardened()) {
7424         run_domtest(elem_test_str, test_elems);
7425         run_domtest(elem_test2_str, test_elems2);
7426         run_domtest(noscript_str, test_noscript);
7427     }else {
7428         skip("IE running in Enhanced Security Configuration\n");
7429     }
7430     run_domtest(doc_blank, test_create_elems);
7431     run_domtest(doc_blank, test_defaults);
7432     run_domtest(doc_blank, test_null_write);
7433     run_domtest(emptydiv_str, test_create_stylesheet);
7434     run_domtest(indent_test_str, test_indent);
7435     run_domtest(cond_comment_str, test_cond_comment);
7436     run_domtest(frameset_str, test_frameset);
7437     run_domtest(emptydiv_str, test_docfrag);
7438     run_domtest(doc_blank, test_replacechild_elems);
7439     run_domtest(doctype_str, test_doctype);
7440
7441     test_quirks_mode();
7442
7443     CoUninitialize();
7444 }