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 #include "precomp.h"
20 
21 #include <stdio.h>
22 
23 static INT (WINAPI *pLCIDToLocaleName)(LCID,LPWSTR,INT,DWORD);
24 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void);
25 
26 static const char doc_blank[] = "<html></html>";
27 static const char doc_str1[] = "<html><body>test</body></html>";
28 static const char range_test_str[] =
29     "<html><body>test \na<font size=\"2\">bc\t123<br /> it's\r\n  \t</font>text<br /></body></html>";
30 static const char range_test2_str[] =
31     "<html><body>abc<hr />123<br /><hr />def</body></html>";
32 static const char elem_test_str[] =
33     "<html><head><title>test</title><style id=\"styleid\">.body { margin-right: 0px; }</style>"
34     "<meta id=\"metaid\" name=\"meta name\" http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
35     "<link id=\"linkid\"></head>"
36     "<body onload=\"Testing()\">text test<!-- a comment -->"
37     "<a id=\"a\" href=\"http://test\" name=\"x\">link</a>"
38     "<label for=\"in\" id=\"labelid\">Label:</label>"
39     "<input id=\"in\" class=\"testclass\" tabIndex=\"2\" title=\"test title\" />"
40     "<button id=\"btnid\"></button>"
41     "<select id=\"s\"><option id=\"x\" value=\"val1\">opt1</option><option id=\"y\">opt2</option></select>"
42     "<textarea id=\"X\">text text</textarea>"
43     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td id=\"td1\">td1 text</td><td id=\"td2\">td2 text</td></tr></tbody></table>"
44     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
45     "<test /><object id=\"objid\" name=\"objname\" vspace=100></object><embed />"
46     "<img id=\"imgid\" name=\"WineImg\"/>"
47     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
48     "<form id=\"frm\"></form>"
49     "<div id=\"attr\" attr1=\"attr1\" attr2 attr3=\"attr3\"></div>"
50     "</body></html>";
51 static const char elem_test2_str[] =
52     "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
53     "<link id=\"linkid\" rel=\"stylesheet\" href=\"about:blank\" type=\"text/css\"></head>"
54     "<body><div id=\"divid\" emptyattr=\"\" onclick=\"parseInt();\"></div></body>"
55     "</html>";
56 
57 static const char indent_test_str[] =
58     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
59 static const char cond_comment_str[] =
60     "<html><head><title>test</title></head><body>"
61     "<!--[if gte IE 4]> <br> <![endif]-->"
62     "</body></html>";
63 static const char frameset_str[] =
64     "<html><head><title>frameset test</title></head><frameset rows=\"25, 25, *\">"
65     "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
66     "<frame src=\"about:blank\" id=\"fr3\">"
67     "</frameset></html>";
68 static const char emptydiv_str[] =
69     "<html><head><title>emptydiv test</title></head>"
70     "<body><div id=\"divid\"></div></body></html>";
71 static const char noscript_str[] =
72     "<html><head><title>noscript test</title><noscript><style>.body { margin-right: 0px; }</style></noscript></head>"
73     "<body><noscript><div>test</div></noscript></body></html>";
74 static const char doctype_str[] =
75     "<!DOCTYPE html>"
76     "<html><head><title>emptydiv test</title></head>"
77     "<body><div id=\"divid\"></div></body></html>";
78 
79 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
80 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
81 static WCHAR wordW[] = {'w','o','r','d',0};
82 
83 typedef enum {
84     ET_NONE,
85     ET_HTML,
86     ET_HEAD,
87     ET_TITLE,
88     ET_BODY,
89     ET_A,
90     ET_INPUT,
91     ET_SELECT,
92     ET_TEXTAREA,
93     ET_OPTION,
94     ET_STYLE,
95     ET_BLOCKQUOTE,
96     ET_P,
97     ET_BR,
98     ET_TABLE,
99     ET_TBODY,
100     ET_SCRIPT,
101     ET_TEST,
102     ET_TESTG,
103     ET_COMMENT,
104     ET_IMG,
105     ET_TR,
106     ET_TD,
107     ET_IFRAME,
108     ET_FORM,
109     ET_FRAME,
110     ET_OBJECT,
111     ET_EMBED,
112     ET_DIV,
113     ET_META,
114     ET_NOSCRIPT,
115     ET_LINK,
116     ET_LABEL,
117     ET_BUTTON
118 } elem_type_t;
119 
120 static const IID * const none_iids[] = {
121     &IID_IUnknown,
122     NULL
123 };
124 
125 static const IID * const doc_node_iids[] = {
126     &IID_IHTMLDOMNode,
127     &IID_IHTMLDOMNode2,
128     &IID_IHTMLDocument,
129     &IID_IHTMLDocument2,
130     &IID_IHTMLDocument3,
131     &IID_IHTMLDocument4,
132     &IID_IHTMLDocument5,
133     &IID_IDispatchEx,
134     &IID_IConnectionPointContainer,
135     &IID_IInternetHostSecurityManager,
136     &IID_IOleContainer,
137     &IID_IObjectSafety,
138     &IID_IProvideClassInfo,
139     NULL
140 };
141 
142 static const IID * const doc_obj_iids[] = {
143     &IID_IHTMLDocument,
144     &IID_IHTMLDocument2,
145     &IID_IHTMLDocument3,
146     &IID_IHTMLDocument4,
147     &IID_IHTMLDocument5,
148     &IID_IDispatchEx,
149     &IID_IConnectionPointContainer,
150     &IID_ICustomDoc,
151     &IID_IOleContainer,
152     &IID_IObjectSafety,
153     &IID_IProvideClassInfo,
154     &IID_ITargetContainer,
155     NULL
156 };
157 
158 #define ELEM_IFACES \
159     &IID_IHTMLDOMNode,  \
160     &IID_IHTMLDOMNode2, \
161     &IID_IHTMLElement,  \
162     &IID_IHTMLElement2, \
163     &IID_IHTMLElement3, \
164     &IID_IHTMLElement4, \
165     &IID_IDispatchEx
166 
167 static const IID * const elem_iids[] = {
168     ELEM_IFACES,
169     &IID_IConnectionPointContainer,
170     NULL
171 };
172 
173 static const IID * const body_iids[] = {
174     ELEM_IFACES,
175     &IID_IHTMLTextContainer,
176     &IID_IHTMLBodyElement,
177     &IID_IConnectionPointContainer,
178     NULL
179 };
180 
181 static const IID * const anchor_iids[] = {
182     ELEM_IFACES,
183     &IID_IHTMLAnchorElement,
184     &IID_IConnectionPointContainer,
185     NULL
186 };
187 
188 static const IID * const input_iids[] = {
189     ELEM_IFACES,
190     &IID_IHTMLInputElement,
191     &IID_IHTMLInputTextElement,
192     &IID_IConnectionPointContainer,
193     NULL
194 };
195 
196 static const IID *const button_iids[] = {
197     ELEM_IFACES,
198     &IID_IHTMLButtonElement,
199     &IID_IConnectionPointContainer,
200     NULL
201 };
202 
203 static const IID * const label_iids[] = {
204     ELEM_IFACES,
205     &IID_IHTMLLabelElement,
206     &IID_IConnectionPointContainer,
207     NULL
208 };
209 
210 static const IID * const select_iids[] = {
211     ELEM_IFACES,
212     &IID_IHTMLSelectElement,
213     &IID_IConnectionPointContainer,
214     NULL
215 };
216 
217 static const IID * const textarea_iids[] = {
218     ELEM_IFACES,
219     &IID_IHTMLTextAreaElement,
220     &IID_IConnectionPointContainer,
221     NULL
222 };
223 
224 static const IID * const option_iids[] = {
225     ELEM_IFACES,
226     &IID_IHTMLOptionElement,
227     &IID_IConnectionPointContainer,
228     NULL
229 };
230 
231 static const IID * const table_iids[] = {
232     ELEM_IFACES,
233     &IID_IHTMLTable,
234     &IID_IHTMLTable2,
235     &IID_IHTMLTable3,
236     &IID_IConnectionPointContainer,
237     NULL
238 };
239 
240 static const IID * const script_iids[] = {
241     ELEM_IFACES,
242     &IID_IHTMLScriptElement,
243     &IID_IConnectionPointContainer,
244     NULL
245 };
246 
247 static const IID * const text_iids[] = {
248     &IID_IHTMLDOMNode,
249     &IID_IHTMLDOMNode2,
250     &IID_IHTMLDOMTextNode,
251     &IID_IHTMLDOMTextNode2,
252     NULL
253 };
254 
255 static const IID * const attr_iids[] = {
256     &IID_IHTMLDOMAttribute,
257     &IID_IHTMLDOMAttribute2,
258     &IID_IDispatchEx,
259     NULL
260 };
261 
262 static const IID * const location_iids[] = {
263     &IID_IDispatch,
264     &IID_IHTMLLocation,
265     NULL
266 };
267 
268 static const IID * const window_iids[] = {
269     &IID_IDispatch,
270     &IID_IHTMLWindow2,
271     &IID_IHTMLWindow3,
272     &IID_IDispatchEx,
273     &IID_IServiceProvider,
274     NULL
275 };
276 
277 static const IID * const comment_iids[] = {
278     ELEM_IFACES,
279     &IID_IHTMLCommentElement,
280     &IID_IConnectionPointContainer,
281     NULL
282 };
283 
284 static const IID * const img_iids[] = {
285     ELEM_IFACES,
286     &IID_IHTMLImgElement,
287     &IID_IConnectionPointContainer,
288     NULL
289 };
290 
291 static const IID * const tr_iids[] = {
292     ELEM_IFACES,
293     &IID_IHTMLTableRow,
294     &IID_IConnectionPointContainer,
295     NULL
296 };
297 
298 static const IID * const td_iids[] = {
299     ELEM_IFACES,
300     &IID_IHTMLTableCell,
301     &IID_IConnectionPointContainer,
302     NULL
303 };
304 
305 static const IID * const frame_iids[] = {
306     ELEM_IFACES,
307     &IID_IHTMLFrameBase,
308     &IID_IHTMLFrameBase2,
309     &IID_IConnectionPointContainer,
310     NULL
311 };
312 
313 static const IID * const head_iids[] = {
314     ELEM_IFACES,
315     &IID_IHTMLHeadElement,
316     &IID_IConnectionPointContainer,
317     NULL
318 };
319 
320 static const IID * const title_iids[] = {
321     ELEM_IFACES,
322     &IID_IHTMLTitleElement,
323     &IID_IConnectionPointContainer,
324     NULL
325 };
326 
327 static const IID * const meta_iids[] = {
328     ELEM_IFACES,
329     &IID_IHTMLMetaElement,
330     &IID_IConnectionPointContainer,
331     NULL
332 };
333 
334 static const IID * const link_iids[] = {
335     ELEM_IFACES,
336     &IID_IHTMLLinkElement,
337     &IID_IConnectionPointContainer,
338     NULL
339 };
340 
341 static const IID * const object_iids[] = {
342     ELEM_IFACES,
343     &IID_IHTMLObjectElement,
344     &IID_IHTMLObjectElement2,
345     /* FIXME: No IConnectionPointContainer */
346     NULL
347 };
348 
349 static const IID * const embed_iids[] = {
350     ELEM_IFACES,
351     &IID_IHTMLEmbedElement,
352     /* FIXME: No IConnectionPointContainer */
353     NULL
354 };
355 
356 static const IID * const iframe_iids[] = {
357     ELEM_IFACES,
358     &IID_IHTMLFrameBase,
359     &IID_IHTMLFrameBase2,
360     &IID_IHTMLIFrameElement,
361     &IID_IHTMLIFrameElement2,
362     &IID_IConnectionPointContainer,
363     NULL
364 };
365 
366 static const IID * const form_iids[] = {
367     ELEM_IFACES,
368     &IID_IHTMLFormElement,
369     &IID_IConnectionPointContainer,
370     &DIID_DispHTMLFormElement,
371     NULL
372 };
373 
374 static const IID * const styleelem_iids[] = {
375     ELEM_IFACES,
376     &IID_IHTMLStyleElement,
377     &IID_IConnectionPointContainer,
378     NULL
379 };
380 
381 static const IID * const generic_iids[] = {
382     ELEM_IFACES,
383     &IID_IHTMLGenericElement,
384     &IID_IConnectionPointContainer,
385     NULL
386 };
387 
388 static const IID * const style_iids[] = {
389     &IID_IUnknown,
390     &IID_IDispatch,
391     &IID_IDispatchEx,
392     &IID_IHTMLStyle,
393     &IID_IHTMLStyle2,
394     &IID_IHTMLStyle3,
395     &IID_IHTMLStyle4,
396     NULL
397 };
398 
399 static const IID * const cstyle_iids[] = {
400     &IID_IUnknown,
401     &IID_IDispatch,
402     &IID_IDispatchEx,
403     &IID_IHTMLCurrentStyle,
404     &IID_IHTMLCurrentStyle2,
405     &IID_IHTMLCurrentStyle3,
406     NULL
407 };
408 
409 static const IID * const img_factory_iids[] = {
410     &IID_IUnknown,
411     &IID_IDispatch,
412     &IID_IDispatchEx,
413     &IID_IHTMLImageElementFactory,
414     NULL
415 };
416 
417 static const IID * const selection_iids[] = {
418     &IID_IUnknown,
419     &IID_IDispatch,
420     &IID_IDispatchEx,
421     &IID_IHTMLSelectionObject,
422     &IID_IHTMLSelectionObject2,
423     NULL
424 };
425 
426 typedef struct {
427     const char *tag;
428     REFIID *iids;
429     const IID *dispiid;
430 } elem_type_info_t;
431 
432 static const elem_type_info_t elem_type_infos[] = {
433     {"",          none_iids,        NULL},
434     {"HTML",      elem_iids,        NULL},
435     {"HEAD",      head_iids,        &DIID_DispHTMLHeadElement},
436     {"TITLE",     title_iids,       &DIID_DispHTMLTitleElement},
437     {"BODY",      body_iids,        &DIID_DispHTMLBody},
438     {"A",         anchor_iids,      &DIID_DispHTMLAnchorElement},
439     {"INPUT",     input_iids,       &DIID_DispHTMLInputElement},
440     {"SELECT",    select_iids,      &DIID_DispHTMLSelectElement},
441     {"TEXTAREA",  textarea_iids,    &DIID_DispHTMLTextAreaElement},
442     {"OPTION",    option_iids,      &DIID_DispHTMLOptionElement},
443     {"STYLE",     styleelem_iids,   &DIID_DispHTMLStyleElement},
444     {"BLOCKQUOTE",elem_iids,        NULL},
445     {"P",         elem_iids,        NULL},
446     {"BR",        elem_iids,        NULL},
447     {"TABLE",     table_iids,       &DIID_DispHTMLTable},
448     {"TBODY",     elem_iids,        NULL},
449     {"SCRIPT",    script_iids,      &DIID_DispHTMLScriptElement},
450     {"TEST",      elem_iids,        &DIID_DispHTMLUnknownElement},
451     {"TEST",      generic_iids,     &DIID_DispHTMLGenericElement},
452     {"!",         comment_iids,     &DIID_DispHTMLCommentElement},
453     {"IMG",       img_iids,         &DIID_DispHTMLImg},
454     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
455     {"TD",        td_iids,          &DIID_DispHTMLTableCell},
456     {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame},
457     {"FORM",      form_iids,        &DIID_DispHTMLFormElement},
458     {"FRAME",     frame_iids,       &DIID_DispHTMLFrameElement},
459     {"OBJECT",    object_iids,      &DIID_DispHTMLObjectElement},
460     {"EMBED",     embed_iids,       &DIID_DispHTMLEmbed},
461     {"DIV",       elem_iids,        NULL},
462     {"META",      meta_iids,        &DIID_DispHTMLMetaElement},
463     {"NOSCRIPT",  elem_iids,        NULL /*&DIID_DispHTMLNoShowElement*/},
464     {"LINK",      link_iids,        &DIID_DispHTMLLinkElement},
465     {"LABEL",     label_iids,       &DIID_DispHTMLLabelElement},
466     {"BUTTON",    button_iids,      &DIID_DispHTMLButtonElement}
467 };
468 
strcmp_wa(LPCWSTR strw,const char * stra)469 static int strcmp_wa(LPCWSTR strw, const char *stra)
470 {
471     CHAR buf[512];
472     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
473     return lstrcmpA(stra, buf);
474 }
475 
is_prefix_wa(const WCHAR * strw,const char * prefix)476 static BOOL is_prefix_wa(const WCHAR *strw, const char *prefix)
477 {
478     int len, prefix_len;
479     CHAR buf[512];
480 
481     len = WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL)-1;
482     prefix_len = lstrlenA(prefix);
483     if(len < prefix_len)
484         return FALSE;
485 
486     buf[prefix_len] = 0;
487     return !lstrcmpA(buf, prefix);
488 }
489 
a2bstr(const char * str)490 static BSTR a2bstr(const char *str)
491 {
492     BSTR ret;
493     int len;
494 
495     if(!str)
496         return NULL;
497 
498     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
499     ret = SysAllocStringLen(NULL, len);
500     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
501 
502     return ret;
503 }
504 
debugstr_variant(const VARIANT * var)505 static const char *debugstr_variant(const VARIANT *var)
506 {
507     static char buf[400];
508 
509     if (!var)
510         return "(null)";
511 
512     switch (V_VT(var))
513     {
514     case VT_EMPTY:
515         return "{VT_EMPTY}";
516     case VT_BSTR:
517         sprintf(buf, "{VT_BSTR: %s}", wine_dbgstr_w(V_BSTR(var)));
518         break;
519     case VT_BOOL:
520         sprintf(buf, "{VT_BOOL: %x}", V_BOOL(var));
521         break;
522     case VT_UI4:
523         sprintf(buf, "{VT_UI4: %u}", V_UI4(var));
524         break;
525     default:
526         sprintf(buf, "{vt %d}", V_VT(var));
527         break;
528     }
529 
530     return buf;
531 }
532 
iface_cmp(IUnknown * iface1,IUnknown * iface2)533 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
534 {
535     IUnknown *unk1, *unk2;
536 
537     if(iface1 == iface2)
538         return TRUE;
539 
540     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
541     IUnknown_Release(unk1);
542     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
543     IUnknown_Release(unk2);
544 
545     return unk1 == unk2;
546 }
547 
create_document(void)548 static IHTMLDocument2 *create_document(void)
549 {
550     IHTMLDocument2 *doc;
551     IHTMLDocument5 *doc5;
552     HRESULT hres;
553 
554     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
555             &IID_IHTMLDocument2, (void**)&doc);
556     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
557     if(FAILED(hres))
558         return NULL;
559 
560     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
561     if(FAILED(hres)) {
562         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
563         IHTMLDocument2_Release(doc);
564         return NULL;
565     }
566 
567     IHTMLDocument5_Release(doc5);
568     return doc;
569 }
570 
571 #define get_dispex_iface(u) _get_dispex_iface(__LINE__,u)
_get_dispex_iface(unsigned line,IUnknown * unk)572 static IDispatchEx *_get_dispex_iface(unsigned line, IUnknown *unk)
573 {
574     IDispatchEx *dispex;
575     HRESULT hres;
576 
577     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
578     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
579     return dispex;
580 }
581 
582 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
_test_ifaces(unsigned line,IUnknown * iface,REFIID * iids)583 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
584 {
585     const IID * const *piid;
586     IUnknown *unk;
587     HRESULT hres;
588 
589      for(piid = iids; *piid; piid++) {
590         hres = IUnknown_QueryInterface(iface, *piid, (void**)&unk);
591         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", wine_dbgstr_guid(*piid), hres);
592         if(SUCCEEDED(hres))
593             IUnknown_Release(unk);
594     }
595 }
596 
597 #define test_no_iface(a,b) _test_no_iface(__LINE__,a,b)
_test_no_iface(unsigned line,IUnknown * iface,REFIID iid)598 static void _test_no_iface(unsigned line, IUnknown *iface, REFIID iid)
599 {
600     IUnknown *unk;
601     HRESULT hres;
602 
603     unk = (void*)0xdeadbeef;
604     hres = IUnknown_QueryInterface(iface, iid, (void**)&unk);
605     ok_(__FILE__,line)(hres == E_NOINTERFACE, "hres = %08x, expected E_NOINTERFACE\n", hres);
606     ok_(__FILE__,line)(!unk, "unk = %p\n", unk);
607 }
608 
609 #define test_get_dispid(u,id) _test_get_dispid(__LINE__,u,id)
_test_get_dispid(unsigned line,IUnknown * unk,IID * iid)610 static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
611 {
612     IDispatchEx *dispex = _get_dispex_iface(line, unk);
613     ITypeInfo *typeinfo;
614     BOOL ret = FALSE;
615     UINT ticnt;
616     HRESULT hres;
617 
618     ticnt = 0xdeadbeef;
619     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
620     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
621     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
622 
623     hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
624     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
625 
626     if(SUCCEEDED(hres)) {
627         TYPEATTR *type_attr;
628 
629         hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
630         ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
631         if(hres == S_OK) {
632             *iid = type_attr->guid;
633             ret = TRUE;
634         }
635 
636         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
637         ITypeInfo_Release(typeinfo);
638     }
639 
640     IDispatchEx_Release(dispex);
641     return ret;
642 }
643 
644 #define test_disp_value(u) _test_disp_value(__LINE__,u,v)
_test_disp_value(unsigned line,IUnknown * unk,const char * val)645 static void _test_disp_value(unsigned line, IUnknown *unk, const char *val)
646 {
647     IDispatchEx *dispex = _get_dispex_iface(line, unk);
648     DISPPARAMS dp  = {NULL,NULL,0,0};
649     EXCEPINFO ei;
650     VARIANT var;
651     HRESULT hres;
652 
653     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
654     IDispatchEx_Release(dispex);
655     ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres);
656 
657     ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var));
658     ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val);
659     VariantClear(&var);
660 }
661 
662 #define test_disp(u,id,v) _test_disp(__LINE__,u,id,v)
_test_disp(unsigned line,IUnknown * unk,const IID * diid,const char * val)663 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val)
664 {
665     IID iid;
666 
667     if(_test_get_dispid(line, unk, &iid))
668         ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", wine_dbgstr_guid(&iid));
669 
670     if(val)
671         _test_disp_value(line, unk, val);
672 }
673 
674 #define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v)
_test_disp2(unsigned line,IUnknown * unk,const IID * diid,const IID * diid2,const char * val)675 static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val)
676 {
677     IID iid;
678 
679     if(_test_get_dispid(line, unk, &iid))
680         ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)),
681                 "unexpected guid %s\n", wine_dbgstr_guid(&iid));
682 
683     if(val)
684         _test_disp_value(line, unk, val);
685 }
686 
687 #define test_class_info(u) _test_class_info(__LINE__,u)
_test_class_info(unsigned line,IUnknown * unk)688 static void _test_class_info(unsigned line, IUnknown *unk)
689 {
690     IProvideClassInfo *classinfo;
691     ITypeInfo *typeinfo;
692     TYPEATTR *type_attr;
693     HRESULT hres;
694 
695     hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo, (void**)&classinfo);
696     ok_(__FILE__,line)(hres == S_OK, "Could not get IProvideClassInfo interface: %08x\n", hres);
697     if(FAILED(hres))
698         return;
699 
700     hres = IProvideClassInfo_GetClassInfo(classinfo, &typeinfo);
701     ok_(__FILE__,line)(hres == S_OK, "Could not get ITypeInfo interface: %08x\n", hres);
702     if(FAILED(hres))
703     {
704         IProvideClassInfo_Release(classinfo);
705         return;
706     }
707 
708     hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
709     ok_(__FILE__,line)(hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
710     if(SUCCEEDED(hres))
711     {
712         ok_(__FILE__,line)(IsEqualGUID(&type_attr->guid, &CLSID_HTMLDocument),
713                 "unexpected guid %s\n", wine_dbgstr_guid(&type_attr->guid));
714         ok_(__FILE__,line)(type_attr->typekind == TKIND_COCLASS,
715                 "unexpected typekind %d\n", type_attr->typekind);
716         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
717     }
718 
719     ITypeInfo_Release(typeinfo);
720     IProvideClassInfo_Release(classinfo);
721 }
722 
723 #define set_dispex_value(a,b,c) _set_dispex_value(__LINE__,a,b,c)
_set_dispex_value(unsigned line,IUnknown * unk,const char * name,VARIANT * val)724 static void _set_dispex_value(unsigned line, IUnknown *unk, const char *name, VARIANT *val)
725 {
726     IDispatchEx *dispex = _get_dispex_iface(line, unk);
727     DISPPARAMS dp = {val, NULL, 1, 0};
728     EXCEPINFO ei;
729     DISPID id;
730     BSTR str;
731     HRESULT hres;
732 
733     str = a2bstr(name);
734     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure|fdexNameCaseInsensitive, &id);
735     SysFreeString(str);
736     ok_(__FILE__,line)(hres == S_OK, "GetDispID failed: %08x\n", hres);
737 
738     memset(&ei, 0, sizeof(ei));
739     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
740     ok_(__FILE__,line)(hres == S_OK, "InvokeEx failed: %08x\n", hres);
741 
742 }
743 
744 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
_get_elem_iface(unsigned line,IUnknown * unk)745 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
746 {
747     IHTMLElement *elem;
748     HRESULT hres;
749 
750     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
751     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres);
752     return elem;
753 }
754 
755 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
_get_elem2_iface(unsigned line,IUnknown * unk)756 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
757 {
758     IHTMLElement2 *elem;
759     HRESULT hres;
760 
761     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem);
762     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres);
763     return elem;
764 }
765 
766 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
_get_elem3_iface(unsigned line,IUnknown * unk)767 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
768 {
769     IHTMLElement3 *elem;
770     HRESULT hres;
771 
772     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem);
773     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres);
774     return elem;
775 }
776 
777 #define get_elem4_iface(u) _get_elem4_iface(__LINE__,u)
_get_elem4_iface(unsigned line,IUnknown * unk)778 static IHTMLElement4 *_get_elem4_iface(unsigned line, IUnknown *unk)
779 {
780     IHTMLElement4 *elem;
781     HRESULT hres;
782 
783     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement4, (void**)&elem);
784     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement4: %08x\n", hres);
785     return elem;
786 }
787 
788 #define get_doc3_iface(u) _get_doc3_iface(__LINE__,u)
_get_doc3_iface(unsigned line,IHTMLDocument2 * doc)789 static IHTMLDocument3 *_get_doc3_iface(unsigned line, IHTMLDocument2 *doc)
790 {
791     IHTMLDocument3 *doc3;
792     HRESULT hres;
793 
794     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
795     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
796 
797     return doc3;
798 }
799 
800 #define get_node_iface(u) _get_node_iface(__LINE__,u)
_get_node_iface(unsigned line,IUnknown * unk)801 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
802 {
803     IHTMLDOMNode *node;
804     HRESULT hres;
805 
806     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node);
807     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres);
808     return node;
809 }
810 
811 #define get_node2_iface(u) _get_node2_iface(__LINE__,u)
_get_node2_iface(unsigned line,IUnknown * unk)812 static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk)
813 {
814     IHTMLDOMNode2 *node;
815     HRESULT hres;
816 
817     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node);
818     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres);
819     return node;
820 }
821 
822 #define get_htmldoc5_iface(u) _get_htmldoc5_iface(__LINE__,u)
_get_htmldoc5_iface(unsigned line,IUnknown * unk)823 static IHTMLDocument5 *_get_htmldoc5_iface(unsigned line, IUnknown *unk)
824 {
825     IHTMLDocument5 *doc;
826     HRESULT hres;
827 
828     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument5, (void**)&doc);
829     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument5: %08x\n", hres);
830     return doc;
831 }
832 
833 #define get_img_iface(u) _get_img_iface(__LINE__,u)
_get_img_iface(unsigned line,IUnknown * unk)834 static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk)
835 {
836     IHTMLImgElement *img;
837     HRESULT hres;
838 
839     hres = IUnknown_QueryInterface(unk, &IID_IHTMLImgElement, (void**)&img);
840     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLImgElement: %08x\n", hres);
841     return img;
842 }
843 
844 #define get_anchor_iface(u) _get_anchor_iface(__LINE__,u)
_get_anchor_iface(unsigned line,IUnknown * unk)845 static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
846 {
847     IHTMLAnchorElement *anchor;
848     HRESULT hres;
849 
850     hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor);
851     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres);
852     return anchor;
853 }
854 
855 #define get_textarea_iface(u) _get_textarea_iface(__LINE__,u)
_get_textarea_iface(unsigned line,IUnknown * unk)856 static IHTMLTextAreaElement *_get_textarea_iface(unsigned line, IUnknown *unk)
857 {
858     IHTMLTextAreaElement *textarea;
859     HRESULT hres;
860 
861     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextAreaElement, (void**)&textarea);
862     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextAreaElement: %08x\n", hres);
863     return textarea;
864 }
865 
866 #define get_select_iface(u) _get_select_iface(__LINE__,u)
_get_select_iface(unsigned line,IUnknown * unk)867 static IHTMLSelectElement *_get_select_iface(unsigned line, IUnknown *unk)
868 {
869     IHTMLSelectElement *select;
870     HRESULT hres;
871 
872     hres = IUnknown_QueryInterface(unk, &IID_IHTMLSelectElement, (void**)&select);
873     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLSelectElement: %08x\n", hres);
874     return select;
875 }
876 
877 #define get_option_iface(u) _get_option_iface(__LINE__,u)
_get_option_iface(unsigned line,IUnknown * unk)878 static IHTMLOptionElement *_get_option_iface(unsigned line, IUnknown *unk)
879 {
880     IHTMLOptionElement *option;
881     HRESULT hres;
882 
883     hres = IUnknown_QueryInterface(unk, &IID_IHTMLOptionElement, (void**)&option);
884     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLOptionElement: %08x\n", hres);
885     return option;
886 }
887 
888 #define get_form_iface(u) _get_form_iface(__LINE__,u)
_get_form_iface(unsigned line,IUnknown * unk)889 static IHTMLFormElement *_get_form_iface(unsigned line, IUnknown *unk)
890 {
891     IHTMLFormElement *form;
892     HRESULT hres;
893 
894     hres = IUnknown_QueryInterface(unk, &IID_IHTMLFormElement, (void**)&form);
895     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLFormElement: %08x\n", hres);
896     return form;
897 }
898 
899 #define get_text_iface(u) _get_text_iface(__LINE__,u)
_get_text_iface(unsigned line,IUnknown * unk)900 static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk)
901 {
902     IHTMLDOMTextNode *text;
903     HRESULT hres;
904 
905     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text);
906     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres);
907     return text;
908 }
909 
910 #define get_text2_iface(u) _get_text2_iface(__LINE__,u)
_get_text2_iface(unsigned line,IUnknown * unk)911 static IHTMLDOMTextNode2 *_get_text2_iface(unsigned line, IUnknown *unk)
912 {
913     IHTMLDOMTextNode2 *text2;
914     HRESULT hres;
915 
916     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode2, (void**)&text2);
917     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode2: %08x\n", hres);
918     return text2;
919 }
920 
921 #define get_comment_iface(u) _get_comment_iface(__LINE__,u)
_get_comment_iface(unsigned line,IUnknown * unk)922 static IHTMLCommentElement *_get_comment_iface(unsigned line, IUnknown *unk)
923 {
924     IHTMLCommentElement *comment;
925     HRESULT hres;
926 
927     hres = IUnknown_QueryInterface(unk, &IID_IHTMLCommentElement, (void**)&comment);
928     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLCommentElement: %08x\n", hres);
929     return comment;
930 }
931 
932 #define get_object_iface(u) _get_object_iface(__LINE__,u)
_get_object_iface(unsigned line,IUnknown * unk)933 static IHTMLObjectElement *_get_object_iface(unsigned line, IUnknown *unk)
934 {
935     IHTMLObjectElement *obj;
936     HRESULT hres;
937 
938     hres = IUnknown_QueryInterface(unk, &IID_IHTMLObjectElement, (void**)&obj);
939     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLObjectElement: %08x\n", hres);
940     return obj;
941 }
942 
943 #define get_style_iface(u) _get_style_iface(__LINE__,u)
_get_style_iface(unsigned line,IUnknown * unk)944 static IHTMLStyleElement *_get_style_iface(unsigned line, IUnknown *unk)
945 {
946     IHTMLStyleElement *obj;
947     HRESULT hres;
948 
949     hres = IUnknown_QueryInterface(unk, &IID_IHTMLStyleElement, (void**)&obj);
950     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLStyleElement: %08x\n", hres);
951     return obj;
952 }
953 
954 #define get_metaelem_iface(u) _get_metaelem_iface(__LINE__,u)
_get_metaelem_iface(unsigned line,IUnknown * unk)955 static IHTMLMetaElement *_get_metaelem_iface(unsigned line, IUnknown *unk)
956 {
957     IHTMLMetaElement *ret;
958     HRESULT hres;
959 
960     hres = IUnknown_QueryInterface(unk, &IID_IHTMLMetaElement, (void**)&ret);
961     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLMetaElement: %08x\n", hres);
962     return ret;
963 }
964 
965 #define get_link_iface(u) _get_link_iface(__LINE__,u)
_get_link_iface(unsigned line,IUnknown * unk)966 static IHTMLLinkElement *_get_link_iface(unsigned line, IUnknown *unk)
967 {
968     IHTMLLinkElement *ret;
969     HRESULT hres;
970 
971     hres = IUnknown_QueryInterface(unk, &IID_IHTMLLinkElement, (void**)&ret);
972     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLinkElement: %08x\n", hres);
973     return ret;
974 }
975 
976 #define get_iframe2_iface(u) _get_iframe2_iface(__LINE__,u)
_get_iframe2_iface(unsigned line,IUnknown * unk)977 static IHTMLIFrameElement2 *_get_iframe2_iface(unsigned line, IUnknown *unk)
978 {
979     IHTMLIFrameElement2 *ret;
980     HRESULT hres;
981 
982     hres = IUnknown_QueryInterface(unk, &IID_IHTMLIFrameElement2, (void**)&ret);
983     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLIFrameElement: %08x\n", hres);
984     return ret;
985 }
986 
987 #define get_button_iface(u) _get_button_iface(__LINE__,u)
_get_button_iface(unsigned line,IUnknown * unk)988 static IHTMLButtonElement *_get_button_iface(unsigned line, IUnknown *unk)
989 {
990     IHTMLButtonElement *ret;
991     HRESULT hres;
992 
993     hres = IUnknown_QueryInterface(unk, &IID_IHTMLButtonElement, (void**)&ret);
994     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLButtonElement: %08x\n", hres);
995     return ret;
996 }
997 
998 #define get_label_iface(u) _get_label_iface(__LINE__,u)
_get_label_iface(unsigned line,IUnknown * unk)999 static IHTMLLabelElement *_get_label_iface(unsigned line, IUnknown *unk)
1000 {
1001     IHTMLLabelElement *ret;
1002     HRESULT hres;
1003 
1004     hres = IUnknown_QueryInterface(unk, &IID_IHTMLLabelElement, (void**)&ret);
1005     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLabelElement: %08x\n", hres);
1006     return ret;
1007 }
1008 
1009 #define get_attr2_iface(u) _get_attr2_iface(__LINE__,u)
_get_attr2_iface(unsigned line,IUnknown * unk)1010 static IHTMLDOMAttribute2 *_get_attr2_iface(unsigned line, IUnknown *unk)
1011 {
1012     IHTMLDOMAttribute2 *ret;
1013     HRESULT hres;
1014 
1015     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMAttribute2, (void**)&ret);
1016     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMAttribute2: %08x\n", hres);
1017     return ret;
1018 }
1019 
1020 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
_test_node_name(unsigned line,IUnknown * unk,const char * exname)1021 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
1022 {
1023     IHTMLDOMNode *node = _get_node_iface(line, unk);
1024     BSTR name;
1025     HRESULT hres;
1026 
1027     hres = IHTMLDOMNode_get_nodeName(node, &name);
1028     IHTMLDOMNode_Release(node);
1029     ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres);
1030     ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname);
1031 
1032     SysFreeString(name);
1033 }
1034 
1035 #define get_owner_doc(u) _get_owner_doc(__LINE__,u)
_get_owner_doc(unsigned line,IUnknown * unk)1036 static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
1037 {
1038     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
1039     IDispatch *disp = (void*)0xdeadbeef;
1040     IHTMLDocument2 *doc = NULL;
1041     HRESULT hres;
1042 
1043     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
1044     IHTMLDOMNode2_Release(node);
1045     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
1046 
1047     if(disp) {
1048         hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
1049         IDispatch_Release(disp);
1050         ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
1051     }
1052 
1053     return doc;
1054 }
1055 
1056 #define get_doc_window(d) _get_doc_window(__LINE__,d)
_get_doc_window(unsigned line,IHTMLDocument2 * doc)1057 static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
1058 {
1059     IHTMLWindow2 *window;
1060     HRESULT hres;
1061 
1062     window = NULL;
1063     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1064     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1065     ok_(__FILE__,line)(window != NULL, "window == NULL\n");
1066 
1067     return window;
1068 }
1069 
1070 #define clone_node(n,d) _clone_node(__LINE__,n,d)
_clone_node(unsigned line,IUnknown * unk,VARIANT_BOOL deep)1071 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
1072 {
1073     IHTMLDOMNode *node = _get_node_iface(line, unk);
1074     IHTMLDOMNode *ret = NULL;
1075     HRESULT hres;
1076 
1077     hres = IHTMLDOMNode_cloneNode(node, deep, &ret);
1078     IHTMLDOMNode_Release(node);
1079     ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres);
1080     ok_(__FILE__,line)(ret != NULL, "ret == NULL\n");
1081 
1082     return ret;
1083 
1084 }
1085 
1086 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
_test_elem_tag(unsigned line,IUnknown * unk,const char * extag)1087 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
1088 {
1089     IHTMLElement *elem = _get_elem_iface(line, unk);
1090     BSTR tag;
1091     HRESULT hres;
1092 
1093     hres = IHTMLElement_get_tagName(elem, &tag);
1094     IHTMLElement_Release(elem);
1095     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
1096     ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
1097 
1098     SysFreeString(tag);
1099 }
1100 
1101 #define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t)
_test_elem_type(unsigned line,IUnknown * unk,elem_type_t type)1102 static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type)
1103 {
1104     _test_elem_tag(line, unk, elem_type_infos[type].tag);
1105     _test_ifaces(line, unk, elem_type_infos[type].iids);
1106 
1107     if(elem_type_infos[type].dispiid && type != ET_A)
1108         _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]");
1109 }
1110 
1111 #define get_node_type(n) _get_node_type(__LINE__,n)
_get_node_type(unsigned line,IUnknown * unk)1112 static LONG _get_node_type(unsigned line, IUnknown *unk)
1113 {
1114     IHTMLDOMNode *node = _get_node_iface(line, unk);
1115     LONG type = -1;
1116     HRESULT hres;
1117 
1118     hres = IHTMLDOMNode_get_nodeType(node, &type);
1119     ok(hres == S_OK, "get_nodeType failed: %08x\n", hres);
1120 
1121     IHTMLDOMNode_Release(node);
1122 
1123     return type;
1124 }
1125 
1126 #define get_child_nodes(u) _get_child_nodes(__LINE__,u)
_get_child_nodes(unsigned line,IUnknown * unk)1127 static IHTMLDOMChildrenCollection *_get_child_nodes(unsigned line, IUnknown *unk)
1128 {
1129     IHTMLDOMNode *node = _get_node_iface(line, unk);
1130     IHTMLDOMChildrenCollection *col = NULL;
1131     IDispatch *disp;
1132     HRESULT hres;
1133 
1134     hres = IHTMLDOMNode_get_childNodes(node, &disp);
1135     IHTMLDOMNode_Release(node);
1136     ok_(__FILE__,line) (hres == S_OK, "get_childNodes failed: %08x\n", hres);
1137     if(FAILED(hres))
1138         return NULL;
1139 
1140     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMChildrenCollection, (void**)&col);
1141     IDispatch_Release(disp);
1142     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMChildrenCollection: %08x\n", hres);
1143 
1144     return col;
1145 }
1146 
1147 #define get_child_item(c,i) _get_child_item(__LINE__,c,i)
_get_child_item(unsigned line,IHTMLDOMChildrenCollection * col,LONG idx)1148 static IHTMLDOMNode *_get_child_item(unsigned line, IHTMLDOMChildrenCollection *col, LONG idx)
1149 {
1150     IHTMLDOMNode *node = NULL;
1151     IDispatch *disp;
1152     HRESULT hres;
1153 
1154     hres = IHTMLDOMChildrenCollection_item(col, idx, &disp);
1155     ok(hres == S_OK, "item failed: %08x\n", hres);
1156 
1157     node = _get_node_iface(line, (IUnknown*)disp);
1158     IDispatch_Release(disp);
1159 
1160     return node;
1161 }
1162 
1163 #define test_elem_attr(e,n,v) _test_elem_attr(__LINE__,e,n,v)
_test_elem_attr(unsigned line,IHTMLElement * elem,const char * name,const char * exval)1164 static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, const char *exval)
1165 {
1166     VARIANT value;
1167     BSTR tmp;
1168     HRESULT hres;
1169 
1170     VariantInit(&value);
1171 
1172     tmp = a2bstr(name);
1173     hres = IHTMLElement_getAttribute(elem, tmp, 0, &value);
1174     SysFreeString(tmp);
1175     ok_(__FILE__,line) (hres == S_OK, "getAttribute failed: %08x\n", hres);
1176 
1177     if(exval) {
1178         ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value));
1179         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value)));
1180     }else {
1181         ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value));
1182     }
1183 
1184     VariantClear(&value);
1185 }
1186 
1187 #define test_elem_offset(a,b) _test_elem_offset(__LINE__,a,b)
_test_elem_offset(unsigned line,IUnknown * unk,const char * parent_tag)1188 static void _test_elem_offset(unsigned line, IUnknown *unk, const char *parent_tag)
1189 {
1190     IHTMLElement *elem = _get_elem_iface(line, unk);
1191     IHTMLElement *off_parent;
1192     LONG l;
1193     HRESULT hres;
1194 
1195     hres = IHTMLElement_get_offsetTop(elem, &l);
1196     ok_(__FILE__,line) (hres == S_OK, "get_offsetTop failed: %08x\n", hres);
1197 
1198     hres = IHTMLElement_get_offsetHeight(elem, &l);
1199     ok_(__FILE__,line) (hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
1200 
1201     hres = IHTMLElement_get_offsetWidth(elem, &l);
1202     ok_(__FILE__,line) (hres == S_OK, "get_offsetWidth failed: %08x\n", hres);
1203 
1204     hres = IHTMLElement_get_offsetLeft(elem, &l);
1205     ok_(__FILE__,line) (hres == S_OK, "get_offsetLeft failed: %08x\n", hres);
1206 
1207     hres = IHTMLElement_get_offsetParent(elem, &off_parent);
1208     ok_(__FILE__,line) (hres == S_OK, "get_offsetParent failed: %08x\n", hres);
1209 
1210     _test_elem_tag(line, (IUnknown*)off_parent, parent_tag);
1211     IHTMLElement_Release(off_parent);
1212 
1213     IHTMLElement_Release(elem);
1214 }
1215 
1216 #define test_elem_source_index(a,b) _test_elem_source_index(__LINE__,a,b)
_test_elem_source_index(unsigned line,IHTMLElement * elem,int index)1217 static void _test_elem_source_index(unsigned line, IHTMLElement *elem, int index)
1218 {
1219     LONG l = 0xdeadbeef;
1220     HRESULT hres;
1221 
1222     hres = IHTMLElement_get_sourceIndex(elem, &l);
1223     ok_(__FILE__,line)(hres == S_OK, "get_sourceIndex failed: %08x\n", hres);
1224     ok_(__FILE__,line)(l == index, "sourceIndex = %d, expected %d\n", l, index);
1225 }
1226 
1227 #define get_doc_node(d) _get_doc_node(__LINE__,d)
_get_doc_node(unsigned line,IHTMLDocument2 * doc)1228 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
1229 {
1230     IHTMLWindow2 *window;
1231     IHTMLDocument2 *ret;
1232     HRESULT hres;
1233 
1234     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1235     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1236 
1237     hres = IHTMLWindow2_get_document(window, &ret);
1238     ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres);
1239     ok_(__FILE__,line)(ret != NULL, "document = NULL\n");
1240 
1241     return ret;
1242 }
1243 
1244 #define test_window_name(d,e) _test_window_name(__LINE__,d,e)
_test_window_name(unsigned line,IHTMLWindow2 * window,const char * exname)1245 static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
1246 {
1247     BSTR name;
1248     HRESULT hres;
1249 
1250     hres = IHTMLWindow2_get_name(window, &name);
1251     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1252     if(exname)
1253         ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
1254     else
1255         ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
1256     SysFreeString(name);
1257 }
1258 
1259 #define set_window_name(w,n) _set_window_name(__LINE__,w,n)
_set_window_name(unsigned line,IHTMLWindow2 * window,const char * name)1260 static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
1261 {
1262     BSTR str;
1263     HRESULT hres;
1264 
1265     str = a2bstr(name);
1266     hres = IHTMLWindow2_put_name(window, str);
1267     SysFreeString(str);
1268     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1269 
1270     _test_window_name(line, window, name);
1271 }
1272 
1273 #define test_window_status(d) _test_window_status(__LINE__,d)
_test_window_status(unsigned line,IHTMLWindow2 * window)1274 static void _test_window_status(unsigned line, IHTMLWindow2 *window)
1275 {
1276     BSTR status;
1277     HRESULT hres;
1278 
1279     status = (void*)0xdeadbeef;
1280     hres = IHTMLWindow2_get_status(window, &status);
1281     ok_(__FILE__,line)(hres == S_OK, "get_status failed: %08x\n", hres);
1282     ok_(__FILE__,line)(!status, "status = %s\n", wine_dbgstr_w(status));
1283     SysFreeString(status);
1284 }
1285 
1286 #define set_window_status(w,n) _set_window_status(__LINE__,w,n)
_set_window_status(unsigned line,IHTMLWindow2 * window,const char * status)1287 static void _set_window_status(unsigned line, IHTMLWindow2 *window, const char *status)
1288 {
1289     BSTR str;
1290     HRESULT hres;
1291 
1292     str = a2bstr(status);
1293     hres = IHTMLWindow2_put_status(window, str);
1294     SysFreeString(str);
1295     ok_(__FILE__,line)(hres == S_OK, "put_status failed: %08x\n", hres);
1296 }
1297 
1298 #define test_window_length(w,l) _test_window_length(__LINE__,w,l)
_test_window_length(unsigned line,IHTMLWindow2 * window,LONG exlen)1299 static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
1300 {
1301     LONG length = -1;
1302     HRESULT hres;
1303 
1304     hres = IHTMLWindow2_get_length(window, &length);
1305     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
1306     ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
1307 }
1308 
1309 #define get_frame_content_window(e) _get_frame_content_window(__LINE__,e)
_get_frame_content_window(unsigned line,IUnknown * elem)1310 static IHTMLWindow2 *_get_frame_content_window(unsigned line, IUnknown *elem)
1311 {
1312     IHTMLFrameBase2 *base2;
1313     IHTMLWindow2 *window;
1314     HRESULT hres;
1315 
1316     hres = IUnknown_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
1317     ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
1318 
1319     window = NULL;
1320     hres = IHTMLFrameBase2_get_contentWindow(base2, &window);
1321     IHTMLFrameBase2_Release(base2);
1322     ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
1323     ok(window != NULL, "contentWindow = NULL\n");
1324 
1325     return window;
1326 }
1327 
test_get_set_attr(IHTMLDocument2 * doc)1328 static void test_get_set_attr(IHTMLDocument2 *doc)
1329 {
1330     IHTMLElement *elem;
1331     IHTMLDocument3 *doc3;
1332     HRESULT hres;
1333     BSTR bstr;
1334     VARIANT val;
1335 
1336     /* grab an element to test with */
1337     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1338     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
1339 
1340     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1341     IHTMLDocument3_Release(doc3);
1342     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
1343 
1344     /* get a non-present attribute */
1345     bstr = a2bstr("notAnAttribute");
1346     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1347     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1348     ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val));
1349     VariantClear(&val);
1350     SysFreeString(bstr);
1351 
1352     /* get a present attribute */
1353     bstr = a2bstr("scrollHeight");
1354     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1355     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1356     ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val));
1357     VariantClear(&val);
1358     SysFreeString(bstr);
1359 
1360     /* create a new BSTR attribute */
1361     bstr = a2bstr("newAttribute");
1362 
1363     V_VT(&val) = VT_BSTR;
1364     V_BSTR(&val) = a2bstr("the value");
1365     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1366     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1367     VariantClear(&val);
1368 
1369     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1370     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1371     ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val));
1372     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)));
1373     VariantClear(&val);
1374 
1375     /* overwrite the attribute with a BOOL */
1376     V_VT(&val) = VT_BOOL;
1377     V_BOOL(&val) = VARIANT_TRUE;
1378     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1379     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1380     VariantClear(&val);
1381 
1382     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1383     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1384     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1385     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1386     VariantClear(&val);
1387 
1388     SysFreeString(bstr);
1389 
1390     /* case-insensitive */
1391     bstr = a2bstr("newattribute");
1392     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1393     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1394     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1395     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1396     VariantClear(&val);
1397     SysFreeString(bstr);
1398 
1399     IHTMLElement_Release(elem);
1400 }
1401 
1402 #define get_doc_elem(d) _get_doc_elem(__LINE__,d)
_get_doc_elem(unsigned line,IHTMLDocument2 * doc)1403 static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc)
1404 {
1405     IHTMLElement *elem;
1406     IHTMLDocument3 *doc3;
1407     HRESULT hres;
1408 
1409     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1410     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
1411     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1412     ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres);
1413     IHTMLDocument3_Release(doc3);
1414 
1415     return elem;
1416 }
1417 
1418 #define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h)
_test_anchor_href(unsigned line,IUnknown * unk,const char * exhref)1419 static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref)
1420 {
1421     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1422     BSTR str;
1423     HRESULT hres;
1424 
1425     hres = IHTMLAnchorElement_get_href(anchor, &str);
1426     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1427     ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref);
1428     SysFreeString(str);
1429 
1430     _test_disp_value(line, unk, exhref);
1431 }
1432 
1433 #define test_anchor_put_href(a,h) _test_anchor_put_href(__LINE__,a,h)
_test_anchor_put_href(unsigned line,IUnknown * unk,const char * exhref)1434 static void _test_anchor_put_href(unsigned line, IUnknown *unk, const char *exhref)
1435 {
1436     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1437     BSTR str;
1438     HRESULT hres;
1439 
1440     str = a2bstr(exhref);
1441     hres = IHTMLAnchorElement_put_href(anchor, str);
1442     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1443     SysFreeString(str);
1444 
1445     _test_disp_value(line, unk, exhref);
1446 }
1447 
1448 #define test_anchor_rel(a,h) _test_anchor_rel(__LINE__,a,h)
_test_anchor_rel(unsigned line,IUnknown * unk,const char * exrel)1449 static void _test_anchor_rel(unsigned line, IUnknown *unk, const char *exrel)
1450 {
1451     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1452     BSTR str;
1453     HRESULT hres;
1454 
1455     hres = IHTMLAnchorElement_get_rel(anchor, &str);
1456     ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
1457     if(exrel)
1458         ok_(__FILE__,line)(!strcmp_wa(str, exrel), "rel = %s, expected %s\n", wine_dbgstr_w(str), exrel);
1459     else
1460         ok_(__FILE__,line)(!str, "rel = %s, expected NULL\n", wine_dbgstr_w(str));
1461     SysFreeString(str);
1462 }
1463 
1464 #define test_anchor_put_rel(a,h) _test_anchor_put_rel(__LINE__,a,h)
_test_anchor_put_rel(unsigned line,IUnknown * unk,const char * exrel)1465 static void _test_anchor_put_rel(unsigned line, IUnknown *unk, const char *exrel)
1466 {
1467     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1468     BSTR str;
1469     HRESULT hres;
1470 
1471     str = a2bstr(exrel);
1472     hres = IHTMLAnchorElement_put_rel(anchor, str);
1473     ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
1474     SysFreeString(str);
1475 }
1476 
1477 #define test_anchor_get_target(a,h) _test_anchor_get_target(__LINE__,a,h)
_test_anchor_get_target(unsigned line,IUnknown * unk,const char * target)1478 static void _test_anchor_get_target(unsigned line, IUnknown *unk, const char *target)
1479 {
1480     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1481     BSTR str;
1482     HRESULT hres;
1483 
1484     hres = IHTMLAnchorElement_get_target(anchor, &str);
1485     ok_(__FILE__,line)(hres == S_OK, "get_target failed: %08x\n", hres);
1486     if(target)
1487         ok_(__FILE__,line)(!strcmp_wa(str, target), "target = %s, expected %s\n", wine_dbgstr_w(str), target);
1488     else
1489         ok_(__FILE__,line)(str == NULL, "target = %s, expected NULL\n", wine_dbgstr_w(str));
1490     SysFreeString(str);
1491 }
1492 
1493 #define test_anchor_put_target(a,h) _test_anchor_put_target(__LINE__,a,h)
_test_anchor_put_target(unsigned line,IUnknown * unk,const char * target)1494 static void _test_anchor_put_target(unsigned line, IUnknown *unk, const char *target)
1495 {
1496     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1497     BSTR str;
1498     HRESULT hres;
1499 
1500     str = target ? a2bstr(target) : NULL;
1501     hres = IHTMLAnchorElement_put_target(anchor, str);
1502     ok_(__FILE__,line)(hres == S_OK, "put_target failed: %08x\n", hres);
1503     SysFreeString(str);
1504 }
1505 
1506 #define test_anchor_name(a,h) _test_anchor_name(__LINE__,a,h)
_test_anchor_name(unsigned line,IUnknown * unk,const char * name)1507 static void _test_anchor_name(unsigned line, IUnknown *unk, const char *name)
1508 {
1509     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1510     BSTR str;
1511     HRESULT hres;
1512 
1513     hres = IHTMLAnchorElement_get_name(anchor, &str);
1514     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1515     if(name)
1516         ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
1517     else
1518         ok_(__FILE__,line)(str == NULL, "name = %s, expected NULL\n", wine_dbgstr_w(str));
1519     SysFreeString(str);
1520 }
1521 
1522 #define test_anchor_put_name(a,h) _test_anchor_put_name(__LINE__,a,h)
_test_anchor_put_name(unsigned line,IUnknown * unk,const char * name)1523 static void _test_anchor_put_name(unsigned line, IUnknown *unk, const char *name)
1524 {
1525     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1526     BSTR str;
1527     HRESULT hres;
1528 
1529     str = name ? a2bstr(name) : NULL;
1530     hres = IHTMLAnchorElement_put_name(anchor, str);
1531     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1532     SysFreeString(str);
1533 
1534     _test_anchor_name(line, unk, name);
1535 }
1536 
1537 #define test_anchor_hostname(a,h) _test_anchor_hostname(__LINE__,a,h)
_test_anchor_hostname(unsigned line,IUnknown * unk,const char * hostname)1538 static void _test_anchor_hostname(unsigned line, IUnknown *unk, const char *hostname)
1539 {
1540     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1541     BSTR str;
1542     HRESULT hres;
1543 
1544     hres = IHTMLAnchorElement_get_hostname(anchor, &str);
1545     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1546     if(hostname)
1547         ok_(__FILE__,line)(!strcmp_wa(str, hostname), "hostname = %s, expected %s\n", wine_dbgstr_w(str), hostname);
1548     else
1549         ok_(__FILE__,line)(str == NULL, "hostname = %s, expected NULL\n", wine_dbgstr_w(str));
1550     SysFreeString(str);
1551 }
1552 
1553 #define test_anchor_search(a,h,n) _test_anchor_search(__LINE__,a,h,n)
_test_anchor_search(unsigned line,IUnknown * elem,const char * search,BOOL allowbroken)1554 static void _test_anchor_search(unsigned line, IUnknown *elem, const char *search, BOOL allowbroken)
1555 {
1556     IHTMLAnchorElement *anchor = _get_anchor_iface(line, elem);
1557     BSTR str;
1558     HRESULT hres;
1559 
1560     hres = IHTMLAnchorElement_get_search(anchor, &str);
1561     ok_(__FILE__,line)(hres == S_OK, "get_search failed: %08x\n", hres);
1562     if ( ! str && allowbroken)
1563         win_skip("skip ie6 incorrect behavior\n");
1564     else if(search)
1565         ok_(__FILE__,line)(!strcmp_wa(str, search), "search = %s, expected %s\n", wine_dbgstr_w(str), search);
1566     else
1567         ok_(__FILE__,line)(!str, "search = %s, expected NULL\n", wine_dbgstr_w(str));
1568     SysFreeString(str);
1569 }
1570 
1571 #define test_anchor_put_search(a,h) _test_anchor_put_search(__LINE__,a,h)
_test_anchor_put_search(unsigned line,IUnknown * unk,const char * search)1572 static void _test_anchor_put_search(unsigned line, IUnknown *unk, const char *search)
1573 {
1574     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1575     BSTR str;
1576     HRESULT hres;
1577 
1578     str = search ? a2bstr(search) : NULL;
1579     hres = IHTMLAnchorElement_put_search(anchor, str);
1580     ok_(__FILE__,line)(hres == S_OK, "put_search failed: %08x\n", hres);
1581     SysFreeString(str);
1582 }
1583 
1584 #define test_anchor_hash(a,h) _test_anchor_hash(__LINE__,a,h)
_test_anchor_hash(unsigned line,IHTMLElement * elem,const char * exhash)1585 static void _test_anchor_hash(unsigned line, IHTMLElement *elem, const char *exhash)
1586 {
1587     IHTMLAnchorElement *anchor = _get_anchor_iface(line, (IUnknown*)elem);
1588     BSTR str;
1589     HRESULT hres;
1590 
1591     hres = IHTMLAnchorElement_get_hash(anchor, &str);
1592     ok_(__FILE__,line)(hres == S_OK, "get_hash failed: %08x\n", hres);
1593     if(exhash)
1594         ok_(__FILE__,line)(!strcmp_wa(str, exhash), "hash = %s, expected %s\n", wine_dbgstr_w(str), exhash);
1595     else
1596         ok_(__FILE__,line)(!str, "hash = %s, expected NULL\n", wine_dbgstr_w(str));
1597     SysFreeString(str);
1598 }
1599 
1600 #define test_option_text(o,t) _test_option_text(__LINE__,o,t)
_test_option_text(unsigned line,IHTMLOptionElement * option,const char * text)1601 static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text)
1602 {
1603     BSTR bstr;
1604     HRESULT hres;
1605 
1606     hres = IHTMLOptionElement_get_text(option, &bstr);
1607     ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres);
1608     ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr));
1609     SysFreeString(bstr);
1610 }
1611 
1612 #define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t)
_test_option_put_text(unsigned line,IHTMLOptionElement * option,const char * text)1613 static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text)
1614 {
1615     BSTR bstr;
1616     HRESULT hres;
1617 
1618     bstr = a2bstr(text);
1619     hres = IHTMLOptionElement_put_text(option, bstr);
1620     SysFreeString(bstr);
1621     ok(hres == S_OK, "put_text failed: %08x\n", hres);
1622 
1623     _test_option_text(line, option, text);
1624 }
1625 
1626 #define test_option_value(o,t) _test_option_value(__LINE__,o,t)
_test_option_value(unsigned line,IHTMLOptionElement * option,const char * value)1627 static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value)
1628 {
1629     BSTR bstr;
1630     HRESULT hres;
1631 
1632     hres = IHTMLOptionElement_get_value(option, &bstr);
1633     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1634     ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr));
1635     SysFreeString(bstr);
1636 }
1637 
1638 #define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t)
_test_option_put_value(unsigned line,IHTMLOptionElement * option,const char * value)1639 static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value)
1640 {
1641     BSTR bstr;
1642     HRESULT hres;
1643 
1644     bstr = a2bstr(value);
1645     hres = IHTMLOptionElement_put_value(option, bstr);
1646     SysFreeString(bstr);
1647     ok(hres == S_OK, "put_value failed: %08x\n", hres);
1648 
1649     _test_option_value(line, option, value);
1650 }
1651 
1652 #define test_option_selected(o,s) _test_option_selected(__LINE__,o,s)
_test_option_selected(unsigned line,IHTMLOptionElement * option,VARIANT_BOOL ex)1653 static void _test_option_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex)
1654 {
1655     VARIANT_BOOL b = 0x100;
1656     HRESULT hres;
1657 
1658     hres = IHTMLOptionElement_get_selected(option, &b);
1659     ok_(__FILE__,line)(hres == S_OK, "get_selected failed: %08x\n", hres);
1660     ok_(__FILE__,line)(b == ex, "selected = %x, expected %x\n", b, ex);
1661 }
1662 
1663 #define test_option_put_selected(o,s) _test_option_put_selected(__LINE__,o,s)
_test_option_put_selected(unsigned line,IHTMLOptionElement * option,VARIANT_BOOL b)1664 static void _test_option_put_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b)
1665 {
1666     HRESULT hres;
1667 
1668     hres = IHTMLOptionElement_put_selected(option, b);
1669     ok_(__FILE__,line)(hres == S_OK, "put_selected failed: %08x\n", hres);
1670     _test_option_selected(line, option, b);
1671 }
1672 
1673 #define test_option_get_index(o,s) _test_option_get_index(__LINE__,o,s)
_test_option_get_index(unsigned line,IHTMLOptionElement * option,LONG exval)1674 static void _test_option_get_index(unsigned line, IHTMLOptionElement *option, LONG exval)
1675 {
1676     HRESULT hres;
1677     LONG val;
1678 
1679     hres = IHTMLOptionElement_get_index(option, NULL);
1680     ok_(__FILE__,line)(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres);
1681 
1682     val = 12345678;
1683     hres = IHTMLOptionElement_get_index(option, &val);
1684     ok_(__FILE__,line)(hres == S_OK, "get_index failed: %08x\n", hres);
1685     ok_(__FILE__,line)(val == exval || broken(val == 12345678),  /* Win2k doesn't touch it*/
1686         "value = %d, expected = %d\n", val, exval);
1687 }
1688 
1689 #define test_option_put_defaultSelected(o,d) _test_option_put_defaultSelected(__LINE__,o,d)
_test_option_put_defaultSelected(unsigned line,IHTMLOptionElement * option,VARIANT_BOOL b)1690 static void _test_option_put_defaultSelected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b)
1691 {
1692     HRESULT hres;
1693 
1694     hres = IHTMLOptionElement_put_defaultSelected(option, b);
1695     ok_(__FILE__,line)(hres == S_OK, "put_defaultSelected %08x\n", hres);
1696 }
1697 
1698 #define test_option_defaultSelected(o,e) _test_option_defaultSelected(__LINE__,o,e)
_test_option_defaultSelected(unsigned line,IHTMLOptionElement * option,VARIANT_BOOL ex)1699 static void _test_option_defaultSelected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex)
1700 {
1701     HRESULT hres;
1702     VARIANT_BOOL b;
1703 
1704     hres = IHTMLOptionElement_get_defaultSelected(option, NULL);
1705     ok_(__FILE__,line)(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres);
1706 
1707     b = 0x100;
1708     hres = IHTMLOptionElement_get_defaultSelected(option, &b);
1709     ok_(__FILE__,line)(hres == S_OK, "get_defaultSelected failed: %08x\n", hres);
1710     ok_(__FILE__,line)(b == ex, "b = %x, expected = %x\n", b, ex);
1711 }
1712 
test_option_defaultSelected_property(IHTMLOptionElement * option)1713 static void test_option_defaultSelected_property(IHTMLOptionElement *option)
1714 {
1715     test_option_defaultSelected(option, VARIANT_FALSE);
1716     test_option_selected(option, VARIANT_FALSE);
1717 
1718     test_option_put_defaultSelected(option, 0x100); /* Invalid value */
1719     test_option_defaultSelected(option, VARIANT_FALSE);
1720     test_option_selected(option, VARIANT_FALSE);
1721 
1722     test_option_put_defaultSelected(option, VARIANT_TRUE);
1723     test_option_defaultSelected(option, VARIANT_TRUE);
1724     test_option_selected(option, VARIANT_FALSE);
1725 
1726     test_option_put_defaultSelected(option, 0x100); /* Invalid value */
1727     test_option_defaultSelected(option, VARIANT_FALSE);
1728     test_option_selected(option, VARIANT_FALSE);
1729 
1730     test_option_put_selected(option, VARIANT_TRUE);
1731     test_option_selected(option, VARIANT_TRUE);
1732     test_option_defaultSelected(option, VARIANT_FALSE);
1733 
1734     test_option_put_defaultSelected(option, VARIANT_TRUE);
1735     test_option_defaultSelected(option, VARIANT_TRUE);
1736     test_option_selected(option, VARIANT_TRUE);
1737 
1738     /* Restore defaultSelected */
1739     test_option_put_defaultSelected(option, VARIANT_TRUE);
1740     test_option_put_selected(option, VARIANT_FALSE);
1741 }
1742 
1743 #define test_textarea_value(t,v) _test_textarea_value(__LINE__,t,v)
_test_textarea_value(unsigned line,IUnknown * unk,const char * exval)1744 static void _test_textarea_value(unsigned line, IUnknown *unk, const char *exval)
1745 {
1746     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1747     BSTR value = (void*)0xdeadbeef;
1748     HRESULT hres;
1749 
1750     hres = IHTMLTextAreaElement_get_value(textarea, &value);
1751     IHTMLTextAreaElement_Release(textarea);
1752     ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres);
1753     if(exval)
1754         ok_(__FILE__,line)(!strcmp_wa(value, exval), "value = %s, expected %s\n", wine_dbgstr_w(value), exval);
1755     else
1756         ok_(__FILE__,line)(!value, "value = %p\n", value);
1757     SysFreeString(value);
1758 }
1759 
1760 #define test_textarea_put_value(t,v) _test_textarea_put_value(__LINE__,t,v)
_test_textarea_put_value(unsigned line,IUnknown * unk,const char * value)1761 static void _test_textarea_put_value(unsigned line, IUnknown *unk, const char *value)
1762 {
1763     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1764     BSTR tmp = a2bstr(value);
1765     HRESULT hres;
1766 
1767     hres = IHTMLTextAreaElement_put_value(textarea, tmp);
1768     IHTMLTextAreaElement_Release(textarea);
1769     ok_(__FILE__,line)(hres == S_OK, "put_value failed: %08x\n", hres);
1770     SysFreeString(tmp);
1771 
1772     _test_textarea_value(line, unk, value);
1773 }
1774 
1775 #define test_textarea_defaultvalue(t,v) _test_textarea_defaultvalue(__LINE__,t,v)
_test_textarea_defaultvalue(unsigned line,IUnknown * unk,const char * exval)1776 static void _test_textarea_defaultvalue(unsigned line, IUnknown *unk, const char *exval)
1777 {
1778     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1779     BSTR value = (void*)0xdeadbeef;
1780     HRESULT hres;
1781 
1782     hres = IHTMLTextAreaElement_get_defaultValue(textarea, &value);
1783     IHTMLTextAreaElement_Release(textarea);
1784     ok_(__FILE__,line)(hres == S_OK, "get_defaultValue failed: %08x\n", hres);
1785     if(exval)
1786         ok_(__FILE__,line)(!strcmp_wa(value, exval), "defaultValue = %s, expected %s\n", wine_dbgstr_w(value), exval);
1787     else
1788         ok_(__FILE__,line)(!value, "value = %p\n", value);
1789     SysFreeString(value);
1790 }
1791 
1792 #define test_textarea_put_defaultvalue(t,v) _test_textarea_put_defaultvalue(__LINE__,t,v)
_test_textarea_put_defaultvalue(unsigned line,IUnknown * unk,const char * value)1793 static void _test_textarea_put_defaultvalue(unsigned line, IUnknown *unk, const char *value)
1794 {
1795     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1796     BSTR tmp = a2bstr(value);
1797     HRESULT hres;
1798 
1799     hres = IHTMLTextAreaElement_put_defaultValue(textarea, tmp);
1800     IHTMLTextAreaElement_Release(textarea);
1801     ok_(__FILE__,line)(hres == S_OK, "put_defaultValue failed: %08x\n", hres);
1802     SysFreeString(tmp);
1803 
1804     _test_textarea_defaultvalue(line, unk, value);
1805 }
1806 
1807 #define test_textarea_readonly(t,v) _test_textarea_readonly(__LINE__,t,v)
_test_textarea_readonly(unsigned line,IUnknown * unk,VARIANT_BOOL ex)1808 static void _test_textarea_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL ex)
1809 {
1810     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1811     VARIANT_BOOL b = 0x100;
1812     HRESULT hres;
1813 
1814     hres = IHTMLTextAreaElement_get_readOnly(textarea, &b);
1815     IHTMLTextAreaElement_Release(textarea);
1816     ok_(__FILE__,line)(hres == S_OK, "get_readOnly failed: %08x\n", hres);
1817     ok_(__FILE__,line)(b == ex, "readOnly = %x, expected %x\n", b, ex);
1818 }
1819 
1820 #define test_textarea_put_readonly(t,v) _test_textarea_put_readonly(__LINE__,t,v)
_test_textarea_put_readonly(unsigned line,IUnknown * unk,VARIANT_BOOL b)1821 static void _test_textarea_put_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL b)
1822 {
1823     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1824     HRESULT hres;
1825 
1826     hres = IHTMLTextAreaElement_put_readOnly(textarea, b);
1827     IHTMLTextAreaElement_Release(textarea);
1828     ok_(__FILE__,line)(hres == S_OK, "put_readOnly failed: %08x\n", hres);
1829 
1830     _test_textarea_readonly(line, unk, b);
1831 }
1832 
1833 #define test_textarea_type(t) _test_textarea_type(__LINE__,t)
_test_textarea_type(unsigned line,IUnknown * unk)1834 static void _test_textarea_type(unsigned line, IUnknown *unk)
1835 {
1836     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1837     BSTR type = (void*)0xdeadbeef;
1838     HRESULT hres;
1839 
1840     hres = IHTMLTextAreaElement_get_type(textarea, &type);
1841     IHTMLTextAreaElement_Release(textarea);
1842     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
1843     ok_(__FILE__,line)(!strcmp_wa(type, "textarea"), "type = %s, expected textarea\n", wine_dbgstr_w(type));
1844     SysFreeString(type);
1845 }
1846 
1847 #define get_textarea_form(t) _get_textarea_form(__LINE__,t)
_get_textarea_form(unsigned line,IUnknown * unk)1848 static IHTMLFormElement *_get_textarea_form(unsigned line, IUnknown *unk)
1849 {
1850     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1851     IHTMLFormElement *form;
1852     HRESULT hres;
1853 
1854     hres = IHTMLTextAreaElement_get_form(textarea, &form);
1855     IHTMLTextAreaElement_Release(textarea);
1856     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
1857 
1858     return form;
1859 }
1860 
1861 #define test_comment_text(c,t) _test_comment_text(__LINE__,c,t)
_test_comment_text(unsigned line,IUnknown * unk,const char * extext)1862 static void _test_comment_text(unsigned line, IUnknown *unk, const char *extext)
1863 {
1864     IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1865     BSTR text;
1866     HRESULT hres;
1867 
1868     text = a2bstr(extext);
1869     hres = IHTMLCommentElement_get_text(comment, &text);
1870     ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
1871     ok_(__FILE__,line)(!strcmp_wa(text, extext), "text = \"%s\", expected \"%s\"\n", wine_dbgstr_w(text), extext);
1872 
1873     IHTMLCommentElement_Release(comment);
1874     SysFreeString(text);
1875 }
1876 
1877 #define test_attr_specified(a,b) _test_attr_specified(__LINE__,a,b)
_test_attr_specified(unsigned line,IHTMLDOMAttribute * attr,VARIANT_BOOL expected)1878 static void _test_attr_specified(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected)
1879 {
1880     VARIANT_BOOL specified;
1881     HRESULT hres;
1882 
1883     hres = IHTMLDOMAttribute_get_specified(attr, &specified);
1884     ok_(__FILE__,line)(hres == S_OK, "get_specified failed: %08x\n", hres);
1885     ok_(__FILE__,line)(specified == expected, "specified = %x, expected %x\n", specified, expected);
1886 }
1887 
1888 #define test_attr_expando(a,b) _test_attr_expando(__LINE__,a,b)
_test_attr_expando(unsigned line,IHTMLDOMAttribute * attr,VARIANT_BOOL expected)1889 static void _test_attr_expando(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected)
1890 {
1891     IHTMLDOMAttribute2 *attr2 = _get_attr2_iface(line, (IUnknown*)attr);
1892     VARIANT_BOOL expando;
1893     HRESULT hres;
1894 
1895     hres = IHTMLDOMAttribute2_get_expando(attr2, &expando);
1896     ok_(__FILE__,line)(hres == S_OK, "get_expando failed: %08x\n", hres);
1897     ok_(__FILE__,line)(expando == expected, "expando = %x, expected %x\n", expando, expected);
1898 
1899     IHTMLDOMAttribute2_Release(attr2);
1900 }
1901 
1902 #define test_attr_value(a,b) _test_attr_value(__LINE__,a,b)
_test_attr_value(unsigned line,IHTMLDOMAttribute * attr,const char * exval)1903 static void _test_attr_value(unsigned line, IHTMLDOMAttribute *attr, const char *exval)
1904 {
1905     IHTMLDOMAttribute2 *attr2 = _get_attr2_iface(line, (IUnknown*)attr);
1906     BSTR val;
1907     HRESULT hres;
1908 
1909     hres = IHTMLDOMAttribute2_get_value(attr2, &val);
1910     ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres);
1911     if(exval)
1912         ok_(__FILE__,line)(!strcmp_wa(val, exval), "value = %s, expected %s\n", wine_dbgstr_w(val), exval);
1913     else
1914         ok_(__FILE__,line)(!val, "value = %s, expected NULL\n", wine_dbgstr_w(val));
1915 
1916     IHTMLDOMAttribute2_Release(attr2);
1917     SysFreeString(val);
1918 }
1919 
1920 #define test_comment_attrs(c) _test_comment_attrs(__LINE__,c)
_test_comment_attrs(unsigned line,IUnknown * unk)1921 static void _test_comment_attrs(unsigned line, IUnknown *unk)
1922 {
1923     IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1924     IHTMLElement *elem = _get_elem_iface(__LINE__,unk);
1925     IHTMLElement4 *elem4 = _get_elem4_iface(__LINE__,unk);
1926     IHTMLDOMAttribute *attr;
1927     BSTR name = a2bstr("test");
1928     VARIANT val;
1929     HRESULT hres;
1930 
1931     hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1932     ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1933     ok(attr == NULL, "attr != NULL\n");
1934 
1935     V_VT(&val) = VT_I4;
1936     V_I4(&val) = 1234;
1937     hres = IHTMLElement_setAttribute(elem, name, val, 0);
1938     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1939 
1940     hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1941     ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1942     ok(attr != NULL, "attr == NULL\n");
1943 
1944     test_attr_expando(attr, VARIANT_TRUE);
1945 
1946     IHTMLDOMAttribute_Release(attr);
1947     IHTMLCommentElement_Release(comment);
1948     IHTMLElement_Release(elem);
1949     IHTMLElement4_Release(elem4);
1950     SysFreeString(name);
1951 }
1952 
1953 #define test_object_vspace(u,s) _test_object_vspace(__LINE__,u,s)
_test_object_vspace(unsigned line,IUnknown * unk,LONG exl)1954 static void _test_object_vspace(unsigned line, IUnknown *unk, LONG exl)
1955 {
1956     IHTMLObjectElement *object = _get_object_iface(line, unk);
1957     LONG l;
1958     HRESULT hres;
1959 
1960     l = 0xdeadbeef;
1961     hres = IHTMLObjectElement_get_vspace(object, &l);
1962     ok_(__FILE__,line)(hres == S_OK, "get_vspace failed: %08x\n", hres);
1963     ok_(__FILE__,line)(l == exl, "vspace=%d, expected %d\n", l, exl);
1964     IHTMLObjectElement_Release(object);
1965 }
1966 
1967 #define test_object_name(a,b) _test_object_name(__LINE__,a,b)
_test_object_name(unsigned line,IHTMLElement * elem,const char * exname)1968 static void _test_object_name(unsigned line, IHTMLElement *elem, const char *exname)
1969 {
1970     IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1971     BSTR str;
1972     HRESULT hres;
1973 
1974     str = (void*)0xdeadbeef;
1975     hres = IHTMLObjectElement_get_name(object, &str);
1976     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1977     if(exname)
1978         ok_(__FILE__,line)(!strcmp_wa(str, exname), "name=%s, expected %s\n", wine_dbgstr_w(str), exname);
1979     else
1980         ok_(__FILE__,line)(!str, "name=%s, expected NULL\n", wine_dbgstr_w(str));
1981     SysFreeString(str);
1982     IHTMLObjectElement_Release(object);
1983 }
1984 
1985 #define set_object_name(a,b) _set_object_name(__LINE__,a,b)
_set_object_name(unsigned line,IHTMLElement * elem,const char * name)1986 static void _set_object_name(unsigned line, IHTMLElement *elem, const char *name)
1987 {
1988     IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1989     BSTR str;
1990     HRESULT hres;
1991 
1992     str = a2bstr(name);
1993     hres = IHTMLObjectElement_put_name(object, str);
1994     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1995     SysFreeString(str);
1996     IHTMLObjectElement_Release(object);
1997 
1998     _test_object_name(line, elem, name);
1999 }
2000 
2001 #define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v)
_create_option_elem(unsigned line,IHTMLDocument2 * doc,const char * txt,const char * val)2002 static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc,
2003         const char *txt, const char *val)
2004 {
2005     IHTMLOptionElementFactory *factory;
2006     IHTMLOptionElement *option;
2007     IHTMLWindow2 *window;
2008     VARIANT text, value, empty;
2009     HRESULT hres;
2010 
2011     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2012     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
2013 
2014     hres = IHTMLWindow2_get_Option(window, &factory);
2015     IHTMLWindow2_Release(window);
2016     ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres);
2017 
2018     test_disp((IUnknown*)factory, &IID_IHTMLOptionElementFactory, "[object]");
2019 
2020     V_VT(&text) = VT_BSTR;
2021     V_BSTR(&text) = a2bstr(txt);
2022     V_VT(&value) = VT_BSTR;
2023     V_BSTR(&value) = a2bstr(val);
2024     V_VT(&empty) = VT_EMPTY;
2025 
2026     hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option);
2027     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
2028 
2029     IHTMLOptionElementFactory_Release(factory);
2030     VariantClear(&text);
2031     VariantClear(&value);
2032 
2033     _test_option_text(line, option, txt);
2034     _test_option_value(line, option, val);
2035     _test_option_selected(line, option, VARIANT_FALSE);
2036 
2037     return option;
2038 }
2039 
2040 #define test_img_width(o,w) _test_img_width(__LINE__,o,w)
_test_img_width(unsigned line,IHTMLImgElement * img,const LONG exp)2041 static void _test_img_width(unsigned line, IHTMLImgElement *img, const LONG exp)
2042 {
2043     LONG found = -1;
2044     HRESULT hres;
2045 
2046     hres = IHTMLImgElement_get_width(img, &found);
2047     ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
2048     ok_(__FILE__,line) (found == exp, "width=%d\n", found);
2049 }
2050 
2051 #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
_test_img_put_width(unsigned line,IHTMLImgElement * img,const LONG width)2052 static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const LONG width)
2053 {
2054     HRESULT hres;
2055 
2056     hres = IHTMLImgElement_put_width(img, width);
2057     ok(hres == S_OK, "put_width failed: %08x\n", hres);
2058 
2059     _test_img_width(line, img, width);
2060 }
2061 
2062 #define test_img_height(o,h) _test_img_height(__LINE__,o,h)
_test_img_height(unsigned line,IHTMLImgElement * img,const LONG exp)2063 static void _test_img_height(unsigned line, IHTMLImgElement *img, const LONG exp)
2064 {
2065     LONG found = -1;
2066     HRESULT hres;
2067 
2068     hres = IHTMLImgElement_get_height(img, &found);
2069     ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
2070     ok_(__FILE__,line) (found == exp, "height=%d\n", found);
2071 }
2072 
2073 #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
_test_img_put_height(unsigned line,IHTMLImgElement * img,const LONG height)2074 static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const LONG height)
2075 {
2076     HRESULT hres;
2077 
2078     hres = IHTMLImgElement_put_height(img, height);
2079     ok(hres == S_OK, "put_height failed: %08x\n", hres);
2080 
2081     _test_img_height(line, img, height);
2082 }
2083 
2084 #define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
_create_img_elem(unsigned line,IHTMLDocument2 * doc,LONG wdth,LONG hght)2085 static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
2086         LONG wdth, LONG hght)
2087 {
2088     IHTMLImageElementFactory *factory;
2089     IHTMLImgElement *img;
2090     IHTMLWindow2 *window;
2091     VARIANT width, height;
2092     char buf[16];
2093     HRESULT hres;
2094 
2095     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2096     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
2097 
2098     hres = IHTMLWindow2_get_Image(window, &factory);
2099     IHTMLWindow2_Release(window);
2100     ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
2101 
2102     test_ifaces((IUnknown*)factory, img_factory_iids);
2103     test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
2104 
2105     if(wdth >= 0){
2106         snprintf(buf, 16, "%d", wdth);
2107         V_VT(&width) = VT_BSTR;
2108         V_BSTR(&width) = a2bstr(buf);
2109     }else{
2110         V_VT(&width) = VT_EMPTY;
2111         wdth = 0;
2112     }
2113 
2114     if(hght >= 0){
2115         snprintf(buf, 16, "%d", hght);
2116         V_VT(&height) = VT_BSTR;
2117         V_BSTR(&height) = a2bstr(buf);
2118     }else{
2119         V_VT(&height) = VT_EMPTY;
2120         hght = 0;
2121     }
2122 
2123     hres = IHTMLImageElementFactory_create(factory, width, height, &img);
2124     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
2125 
2126     IHTMLImageElementFactory_Release(factory);
2127     VariantClear(&width);
2128     VariantClear(&height);
2129 
2130     if(SUCCEEDED(hres)) {
2131         _test_img_width(line, img, wdth);
2132         _test_img_height(line, img, hght);
2133         return img;
2134     }
2135 
2136     return NULL;
2137 }
2138 
2139 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
_test_select_length(unsigned line,IHTMLSelectElement * select,LONG length)2140 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
2141 {
2142     LONG len = 0xdeadbeef;
2143     HRESULT hres;
2144 
2145     hres = IHTMLSelectElement_get_length(select, &len);
2146     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
2147     ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length);
2148 }
2149 
2150 #define test_select_put_length(s,l) _test_select_put_length(__LINE__,s,l)
_test_select_put_length(unsigned line,IUnknown * unk,LONG length)2151 static void _test_select_put_length(unsigned line, IUnknown *unk, LONG length)
2152 {
2153     IHTMLSelectElement *select = _get_select_iface(line, unk);
2154     HRESULT hres;
2155 
2156     hres = IHTMLSelectElement_put_length(select, length);
2157     ok_(__FILE__,line) (hres == S_OK, "put_length failed: %08x\n", hres);
2158     _test_select_length(line, select, length);
2159     IHTMLSelectElement_Release(select);
2160 }
2161 
2162 #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i)
_test_select_selidx(unsigned line,IHTMLSelectElement * select,LONG index)2163 static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
2164 {
2165     LONG idx = 0xdeadbeef;
2166     HRESULT hres;
2167 
2168     hres = IHTMLSelectElement_get_selectedIndex(select, &idx);
2169     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
2170     ok_(__FILE__,line) (idx == index, "idx=%d, expected %d\n", idx, index);
2171 }
2172 
2173 #define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i)
_test_select_put_selidx(unsigned line,IHTMLSelectElement * select,LONG index)2174 static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
2175 {
2176     HRESULT hres;
2177 
2178     hres = IHTMLSelectElement_put_selectedIndex(select, index);
2179     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
2180     _test_select_selidx(line, select, index);
2181 }
2182 
2183 #define test_select_value(s,v) _test_select_value(__LINE__,s,v)
_test_select_value(unsigned line,IHTMLSelectElement * select,const char * exval)2184 static void _test_select_value(unsigned line, IHTMLSelectElement *select, const char *exval)
2185 {
2186     BSTR val;
2187     HRESULT hres;
2188 
2189     hres = IHTMLSelectElement_get_value(select, &val);
2190     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
2191     if(exval)
2192         ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val));
2193     else
2194         ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val));
2195     SysFreeString(val);
2196 }
2197 
2198 #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v)
_test_select_set_value(unsigned line,IHTMLSelectElement * select,const char * val)2199 static void _test_select_set_value(unsigned line, IHTMLSelectElement *select, const char *val)
2200 {
2201     BSTR bstr;
2202     HRESULT hres;
2203 
2204     bstr = a2bstr(val);
2205     hres = IHTMLSelectElement_put_value(select, bstr);
2206     SysFreeString(bstr);
2207     ok_(__FILE__,line) (hres == S_OK, "put_value failed: %08x\n", hres);
2208 }
2209 
2210 #define test_select_type(s,t) _test_select_type(__LINE__,s,t)
_test_select_type(unsigned line,IHTMLSelectElement * select,const char * extype)2211 static void _test_select_type(unsigned line, IHTMLSelectElement *select, const char *extype)
2212 {
2213     BSTR type;
2214     HRESULT hres;
2215 
2216     hres = IHTMLSelectElement_get_type(select, &type);
2217     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
2218     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
2219     SysFreeString(type);
2220 }
2221 
2222 #define test_select_multiple(s,t) _test_select_multiple(__LINE__,s,t)
_test_select_multiple(unsigned line,IHTMLSelectElement * select,VARIANT_BOOL exmultiple)2223 static void _test_select_multiple(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exmultiple)
2224 {
2225     VARIANT_BOOL b = 100;
2226     HRESULT hres;
2227 
2228     hres = IHTMLSelectElement_get_multiple(select, &b);
2229     ok_(__FILE__,line) (hres == S_OK, "get_multiple failed: %08x\n", hres);
2230     ok_(__FILE__,line) (b == exmultiple, "multiple=%x, expected %x\n", b, exmultiple);
2231 }
2232 
2233 #define test_select_set_multiple(s,v) _test_select_set_multiple(__LINE__,s,v)
_test_select_set_multiple(unsigned line,IHTMLSelectElement * select,VARIANT_BOOL val)2234 static void _test_select_set_multiple(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL val)
2235 {
2236     HRESULT hres;
2237 
2238     hres = IHTMLSelectElement_put_multiple(select, val);
2239     ok_(__FILE__,line) (hres == S_OK, "put_multiple failed: %08x\n", hres);
2240 
2241     _test_select_multiple(line, select, val);
2242 }
2243 
2244 #define test_select_size(s,v) _test_select_size(__LINE__,s,v)
_test_select_size(unsigned line,IHTMLSelectElement * select,LONG exval)2245 static void _test_select_size(unsigned line, IHTMLSelectElement *select, LONG exval)
2246 {
2247     HRESULT hres;
2248     LONG val;
2249 
2250     hres = IHTMLSelectElement_get_size(select, NULL);
2251     ok_(__FILE__,line) (hres == E_INVALIDARG, "got %08x, expected E_INVALIDARG\n", hres);
2252 
2253     val = 0xdeadbeef;
2254     hres = IHTMLSelectElement_get_size(select, &val);
2255     ok_(__FILE__,line) (hres == S_OK, "get_size failed: %08x\n", hres);
2256     ok_(__FILE__,line) (val == exval, "size = %d, expected %d\n", val, exval);
2257 }
2258 
2259 #define test_select_set_size(s,v,e) _test_select_set_size(__LINE__,s,v,e)
_test_select_set_size(unsigned line,IHTMLSelectElement * select,LONG val,HRESULT exhres)2260 static void _test_select_set_size(unsigned line, IHTMLSelectElement *select, LONG val, HRESULT exhres)
2261 {
2262     HRESULT hres;
2263 
2264     hres = IHTMLSelectElement_put_size(select, val);
2265     ok_(__FILE__,line) (hres == exhres, "put_size(%d) got %08x, expect %08x\n", val, hres, exhres);
2266 }
2267 
2268 #define test_select_name(s,v) _test_select_name(__LINE__,s,v)
_test_select_name(unsigned line,IHTMLSelectElement * select,const char * extext)2269 static void _test_select_name(unsigned line, IHTMLSelectElement *select, const char *extext)
2270 {
2271     HRESULT hres;
2272     BSTR text;
2273 
2274     text = NULL;
2275     hres = IHTMLSelectElement_get_name(select, &text);
2276     ok_(__FILE__,line) (hres == S_OK, "get_name failed: %08x\n", hres);
2277     if(extext) {
2278         ok_(__FILE__,line) (text != NULL, "text == NULL\n");
2279         ok_(__FILE__,line) (!strcmp_wa(text, extext), "name = %s, expected %s\n",
2280             wine_dbgstr_w(text), extext);
2281         SysFreeString(text);
2282     } else
2283         ok_(__FILE__,line) (text == NULL, "text(%p) = %s\n", text, wine_dbgstr_w(text));
2284 }
2285 
2286 #define test_select_set_name(s,v) _test_select_set_name(__LINE__,s,v)
_test_select_set_name(unsigned line,IHTMLSelectElement * select,const char * text)2287 static void _test_select_set_name(unsigned line, IHTMLSelectElement *select, const char *text)
2288 {
2289     HRESULT hres;
2290     BSTR bstr;
2291 
2292     bstr = a2bstr(text);
2293 
2294     hres = IHTMLSelectElement_put_name(select, bstr);
2295     ok_(__FILE__,line) (hres == S_OK, "put_name(%s) failed: %08x\n", wine_dbgstr_w(bstr), hres);
2296     SysFreeString(bstr);
2297 }
2298 
2299 #define test_range_text(r,t) _test_range_text(__LINE__,r,t)
_test_range_text(unsigned line,IHTMLTxtRange * range,const char * extext)2300 static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext)
2301 {
2302     BSTR text;
2303     HRESULT hres;
2304 
2305     hres = IHTMLTxtRange_get_text(range, &text);
2306     ok_(__FILE__, line) (hres == S_OK, "get_text failed: %08x\n", hres);
2307 
2308     if(extext) {
2309         ok_(__FILE__, line) (text != NULL, "text == NULL\n");
2310         ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext);
2311     }else {
2312         ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text));
2313     }
2314 
2315     SysFreeString(text);
2316 
2317 }
2318 
2319 #define test_range_collapse(r,b) _test_range_collapse(__LINE__,r,b)
_test_range_collapse(unsigned line,IHTMLTxtRange * range,BOOL b)2320 static void _test_range_collapse(unsigned line, IHTMLTxtRange *range, BOOL b)
2321 {
2322     HRESULT hres;
2323 
2324     hres = IHTMLTxtRange_collapse(range, b);
2325     ok_(__FILE__, line) (hres == S_OK, "collapse failed: %08x\n", hres);
2326     _test_range_text(line, range, NULL);
2327 }
2328 
2329 #define test_range_expand(r,u,b,t) _test_range_expand(__LINE__,r,u,b,t)
_test_range_expand(unsigned line,IHTMLTxtRange * range,LPWSTR unit,VARIANT_BOOL exb,const char * extext)2330 static void _test_range_expand(unsigned line, IHTMLTxtRange *range, LPWSTR unit,
2331         VARIANT_BOOL exb, const char *extext)
2332 {
2333     VARIANT_BOOL b = 0xe0e0;
2334     HRESULT hres;
2335 
2336     hres = IHTMLTxtRange_expand(range, unit, &b);
2337     ok_(__FILE__,line) (hres == S_OK, "expand failed: %08x\n", hres);
2338     ok_(__FILE__,line) (b == exb, "b=%x, expected %x\n", b, exb);
2339     _test_range_text(line, range, extext);
2340 }
2341 
2342 #define test_range_move(r,u,c,e) _test_range_move(__LINE__,r,u,c,e)
_test_range_move(unsigned line,IHTMLTxtRange * range,LPWSTR unit,LONG cnt,LONG excnt)2343 static void _test_range_move(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
2344 {
2345     LONG c = 0xdeadbeef;
2346     HRESULT hres;
2347 
2348     hres = IHTMLTxtRange_move(range, unit, cnt, &c);
2349     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
2350     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
2351     _test_range_text(line, range, NULL);
2352 }
2353 
2354 #define test_range_movestart(r,u,c,e) _test_range_movestart(__LINE__,r,u,c,e)
_test_range_movestart(unsigned line,IHTMLTxtRange * range,LPWSTR unit,LONG cnt,LONG excnt)2355 static void _test_range_movestart(unsigned line, IHTMLTxtRange *range,
2356         LPWSTR unit, LONG cnt, LONG excnt)
2357 {
2358     LONG c = 0xdeadbeef;
2359     HRESULT hres;
2360 
2361     hres = IHTMLTxtRange_moveStart(range, unit, cnt, &c);
2362     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
2363     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
2364 }
2365 
2366 #define test_range_moveend(r,u,c,e) _test_range_moveend(__LINE__,r,u,c,e)
_test_range_moveend(unsigned line,IHTMLTxtRange * range,LPWSTR unit,LONG cnt,LONG excnt)2367 static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
2368 {
2369     LONG c = 0xdeadbeef;
2370     HRESULT hres;
2371 
2372     hres = IHTMLTxtRange_moveEnd(range, unit, cnt, &c);
2373     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
2374     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
2375 }
2376 
2377 #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
_test_range_put_text(unsigned line,IHTMLTxtRange * range,const char * text)2378 static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
2379 {
2380     HRESULT hres;
2381     BSTR bstr = a2bstr(text);
2382 
2383     hres = IHTMLTxtRange_put_text(range, bstr);
2384     ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
2385     SysFreeString(bstr);
2386     _test_range_text(line, range, NULL);
2387 }
2388 
2389 #define test_range_inrange(r1,r2,b) _test_range_inrange(__LINE__,r1,r2,b)
_test_range_inrange(unsigned line,IHTMLTxtRange * range1,IHTMLTxtRange * range2,VARIANT_BOOL exb)2390 static void _test_range_inrange(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
2391 {
2392     VARIANT_BOOL b;
2393     HRESULT hres;
2394 
2395     b = 0xe0e0;
2396     hres = IHTMLTxtRange_inRange(range1, range2, &b);
2397     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
2398     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
2399 }
2400 
2401 #define test_range_isequal(r1,r2,b) _test_range_isequal(__LINE__,r1,r2,b)
_test_range_isequal(unsigned line,IHTMLTxtRange * range1,IHTMLTxtRange * range2,VARIANT_BOOL exb)2402 static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
2403 {
2404     VARIANT_BOOL b;
2405     HRESULT hres;
2406 
2407     b = 0xe0e0;
2408     hres = IHTMLTxtRange_isEqual(range1, range2, &b);
2409     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
2410     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
2411 
2412     b = 0xe0e0;
2413     hres = IHTMLTxtRange_isEqual(range2, range1, &b);
2414     ok_(__FILE__,line) (hres == S_OK, "(2->1) isEqual failed: %08x\n", hres);
2415     ok_(__FILE__,line) (b == exb, "(2->1) b=%x, expected %x\n", b, exb);
2416 
2417     if(exb) {
2418         test_range_inrange(range1, range2, VARIANT_TRUE);
2419         test_range_inrange(range2, range1, VARIANT_TRUE);
2420     }
2421 }
2422 
2423 #define test_range_paste_html(a,b) _test_range_paste_html(__LINE__,a,b)
_test_range_paste_html(unsigned line,IHTMLTxtRange * range,const char * html)2424 static void _test_range_paste_html(unsigned line, IHTMLTxtRange *range, const char *html)
2425 {
2426     BSTR str = a2bstr(html);
2427     HRESULT hres;
2428 
2429     hres = IHTMLTxtRange_pasteHTML(range, str);
2430     ok_(__FILE__,line)(hres == S_OK, "pasteHTML failed: %08x\n", hres);
2431     SysFreeString(str);
2432 }
2433 
2434 #define test_range_parent(r,t) _test_range_parent(__LINE__,r,t)
_test_range_parent(unsigned line,IHTMLTxtRange * range,elem_type_t type)2435 static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t type)
2436 {
2437     IHTMLElement *elem;
2438     HRESULT hres;
2439 
2440     hres = IHTMLTxtRange_parentElement(range, &elem);
2441     ok_(__FILE__,line) (hres == S_OK, "parentElement failed: %08x\n", hres);
2442 
2443     _test_elem_type(line, (IUnknown*)elem, type);
2444 
2445     IHTMLElement_Release(elem);
2446 }
2447 
2448 #define get_elem_col_item_idx(a,b) _get_elem_col_item_idx(__LINE__,a,b)
_get_elem_col_item_idx(unsigned line,IHTMLElementCollection * col,int i)2449 static IHTMLElement *_get_elem_col_item_idx(unsigned line, IHTMLElementCollection *col, int i)
2450 {
2451     VARIANT name, index;
2452     IHTMLElement *elem;
2453     IDispatch *disp;
2454     HRESULT hres;
2455 
2456     V_VT(&index) = VT_EMPTY;
2457     V_VT(&name) = VT_I4;
2458     V_I4(&name) = i;
2459     hres = IHTMLElementCollection_item(col, name, index, &disp);
2460     ok_(__FILE__,line)(hres == S_OK, "item failed: %08x\n", hres);
2461     ok_(__FILE__,line)(disp != NULL, "disp == NULL\n");
2462 
2463     elem = _get_elem_iface(line, (IUnknown*)disp);
2464     IDispatch_Release(disp);
2465     return elem;
2466 }
2467 
2468 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
_test_elem_collection(unsigned line,IUnknown * unk,const elem_type_t * elem_types,LONG exlen)2469 static void _test_elem_collection(unsigned line, IUnknown *unk,
2470         const elem_type_t *elem_types, LONG exlen)
2471 {
2472     IHTMLElementCollection *col;
2473     IEnumVARIANT *enum_var;
2474     IUnknown *enum_unk;
2475     ULONG fetched;
2476     LONG len;
2477     DWORD i;
2478     VARIANT name, index, v, vs[5];
2479     IDispatch *disp, *disp2;
2480     HRESULT hres;
2481 
2482     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col);
2483     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres);
2484 
2485     test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]");
2486 
2487     hres = IHTMLElementCollection_get_length(col, &len);
2488     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
2489     ok_(__FILE__,line) (len == exlen, "len=%d, expected %d\n", len, exlen);
2490 
2491     if(len > exlen)
2492         len = exlen;
2493 
2494     V_VT(&index) = VT_EMPTY;
2495 
2496     hres = IHTMLElementCollection_get__newEnum(col, &enum_unk);
2497     ok_(__FILE__,line)(hres == S_OK, "_newEnum failed: %08x\n", hres);
2498 
2499     hres = IUnknown_QueryInterface(enum_unk, &IID_IEnumVARIANT, (void**)&enum_var);
2500     IUnknown_Release(enum_unk);
2501     ok_(__FILE__,line)(hres == S_OK, "Could not get IEnumVARIANT iface: %08x\n", hres);
2502 
2503     for(i=0; i<len; i++) {
2504         V_VT(&name) = VT_I4;
2505         V_I4(&name) = i;
2506         disp = (void*)0xdeadbeef;
2507         hres = IHTMLElementCollection_item(col, name, index, &disp);
2508         ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2509         ok_(__FILE__,line) (disp != NULL, "item returned NULL\n");
2510         if(FAILED(hres) || !disp)
2511             continue;
2512 
2513         _test_elem_type(line, (IUnknown*)disp, elem_types[i]);
2514 
2515         if(!i) {
2516             V_VT(&name) = VT_UINT;
2517             V_I4(&name) = 0;
2518             disp2 = (void*)0xdeadbeef;
2519             hres = IHTMLElementCollection_item(col, name, index, &disp2);
2520             ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2521             ok_(__FILE__,line) (iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
2522             if(disp2)
2523                 IDispatch_Release(disp2);
2524         }
2525 
2526         fetched = 0;
2527         V_VT(&v) = VT_ERROR;
2528         hres = IEnumVARIANT_Next(enum_var, 1, &v, i ? &fetched : NULL);
2529         ok_(__FILE__,line)(hres == S_OK, "Next failed: %08x\n", hres);
2530         if(i)
2531             ok_(__FILE__,line)(fetched == 1, "fetched = %d\n", fetched);
2532         ok_(__FILE__,line)(V_VT(&v) == VT_DISPATCH && V_DISPATCH(&v), "V_VT(v) = %d\n", V_VT(&v));
2533         ok_(__FILE__,line)(iface_cmp((IUnknown*)disp, (IUnknown*)V_DISPATCH(&v)), "disp != V_DISPATCH(v)\n");
2534         IDispatch_Release(V_DISPATCH(&v));
2535 
2536         IDispatch_Release(disp);
2537     }
2538 
2539     fetched = 0xdeadbeef;
2540     V_VT(&v) = VT_BOOL;
2541     hres = IEnumVARIANT_Next(enum_var, 1, &v, &fetched);
2542     ok_(__FILE__,line)(hres == S_FALSE, "Next returned %08x, expected S_FALSE\n", hres);
2543     ok_(__FILE__,line)(fetched == 0, "fetched = %d\n", fetched);
2544     ok_(__FILE__,line)(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2545 
2546     hres = IEnumVARIANT_Reset(enum_var);
2547     ok_(__FILE__,line)(hres == S_OK, "Reset failed: %08x\n", hres);
2548 
2549     fetched = 0xdeadbeef;
2550     V_VT(&v) = VT_BOOL;
2551     hres = IEnumVARIANT_Next(enum_var, 0, &v, &fetched);
2552     ok_(__FILE__,line)(hres == S_OK, "Next returned %08x, expected S_FALSE\n", hres);
2553     ok_(__FILE__,line)(fetched == 0, "fetched = %d\n", fetched);
2554     ok_(__FILE__,line)(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2555 
2556     hres = IEnumVARIANT_Skip(enum_var, len > 2 ? len-2 : 0);
2557     ok_(__FILE__,line)(hres == S_OK, "Skip failed: %08x\n", hres);
2558 
2559     memset(vs, 0, sizeof(vs));
2560     fetched = 0;
2561     hres = IEnumVARIANT_Next(enum_var, sizeof(vs)/sizeof(*vs), vs, &fetched);
2562     ok_(__FILE__,line)(hres == S_FALSE, "Next failed: %08x\n", hres);
2563     ok_(__FILE__,line)(fetched == (len > 2 ? 2 : len), "fetched = %d\n", fetched);
2564     if(len) {
2565         ok_(__FILE__,line)(V_VT(vs) == VT_DISPATCH && V_DISPATCH(vs), "V_VT(vs[0]) = %d\n", V_VT(vs));
2566         IDispatch_Release(V_DISPATCH(vs));
2567     }
2568     if(len > 1) {
2569         ok_(__FILE__,line)(V_VT(vs+1) == VT_DISPATCH && V_DISPATCH(vs+1), "V_VT(vs[1]) = %d\n", V_VT(vs+1));
2570         IDispatch_Release(V_DISPATCH(vs+1));
2571     }
2572 
2573     hres = IEnumVARIANT_Reset(enum_var);
2574     ok_(__FILE__,line)(hres == S_OK, "Reset failed: %08x\n", hres);
2575 
2576     hres = IEnumVARIANT_Skip(enum_var, len+1);
2577     ok_(__FILE__,line)(hres == S_FALSE, "Skip failed: %08x\n", hres);
2578 
2579     IEnumVARIANT_Release(enum_var);
2580 
2581     V_VT(&name) = VT_I4;
2582     V_I4(&name) = len;
2583     disp = (void*)0xdeadbeef;
2584     hres = IHTMLElementCollection_item(col, name, index, &disp);
2585     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2586     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2587 
2588     V_VT(&name) = VT_UI4;
2589     V_I4(&name) = len;
2590     disp = (void*)0xdeadbeef;
2591     hres = IHTMLElementCollection_item(col, name, index, &disp);
2592     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2593     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2594 
2595     V_VT(&name) = VT_INT;
2596     V_I4(&name) = len;
2597     disp = (void*)0xdeadbeef;
2598     hres = IHTMLElementCollection_item(col, name, index, &disp);
2599     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2600     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2601 
2602     V_VT(&name) = VT_UINT;
2603     V_I4(&name) = len;
2604     disp = (void*)0xdeadbeef;
2605     hres = IHTMLElementCollection_item(col, name, index, &disp);
2606     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2607     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2608 
2609     V_VT(&name) = VT_I4;
2610     V_I4(&name) = -1;
2611     disp = (void*)0xdeadbeef;
2612     hres = IHTMLElementCollection_item(col, name, index, &disp);
2613     ok_(__FILE__,line) (hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
2614     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2615 
2616     IHTMLElementCollection_Release(col);
2617 }
2618 
2619 #define test_elem_all(c,t,l) _test_elem_all(__LINE__,c,t,l)
_test_elem_all(unsigned line,IUnknown * unk,const elem_type_t * elem_types,LONG exlen)2620 static void _test_elem_all(unsigned line, IUnknown *unk, const elem_type_t *elem_types, LONG exlen)
2621 {
2622     IHTMLElement *elem = _get_elem_iface(line, unk);
2623     IDispatch *disp;
2624     HRESULT hres;
2625 
2626     hres = IHTMLElement_get_all(elem, &disp);
2627     IHTMLElement_Release(elem);
2628     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2629 
2630     _test_elem_collection(line, (IUnknown*)disp, elem_types, exlen);
2631     IDispatch_Release(disp);
2632 }
2633 
2634 #define test_doc_all(a,b,c) _test_doc_all(__LINE__,a,b,c)
_test_doc_all(unsigned line,IHTMLDocument2 * doc,const elem_type_t * elem_types,LONG exlen)2635 static void _test_doc_all(unsigned line, IHTMLDocument2 *doc, const elem_type_t *elem_types, LONG exlen)
2636 {
2637     IHTMLElementCollection *col;
2638     HRESULT hres;
2639 
2640     hres = IHTMLDocument2_get_all(doc, &col);
2641     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2642 
2643     _test_elem_collection(line, (IUnknown*)col, elem_types, exlen);
2644     IHTMLElementCollection_Release(col);
2645 }
2646 
2647 #define test_elem_getelembytag(a,b,c,d) _test_elem_getelembytag(__LINE__,a,b,c,d)
_test_elem_getelembytag(unsigned line,IUnknown * unk,elem_type_t type,LONG exlen,IHTMLElement ** ret)2648 static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t type, LONG exlen, IHTMLElement **ret)
2649 {
2650     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2651     IHTMLElementCollection *col = NULL;
2652     elem_type_t *types = NULL;
2653     BSTR tmp;
2654     int i;
2655     HRESULT hres;
2656 
2657     tmp = a2bstr(elem_type_infos[type].tag);
2658     hres = IHTMLElement2_getElementsByTagName(elem, tmp, &col);
2659     SysFreeString(tmp);
2660     IHTMLElement2_Release(elem);
2661     ok_(__FILE__,line) (hres == S_OK, "getElementByTagName failed: %08x\n", hres);
2662     ok_(__FILE__,line) (col != NULL, "col == NULL\n");
2663 
2664     if(exlen) {
2665         types = HeapAlloc(GetProcessHeap(), 0, exlen*sizeof(elem_type_t));
2666         for(i=0; i<exlen; i++)
2667             types[i] = type;
2668     }
2669 
2670     _test_elem_collection(line, (IUnknown*)col, types, exlen);
2671 
2672     HeapFree(GetProcessHeap(), 0, types);
2673 
2674     if(ret)
2675         *ret = get_elem_col_item_idx(col, 0);
2676     IHTMLElementCollection_Release(col);
2677 }
2678 
2679 #define test_elem_innertext(e,t) _test_elem_innertext(__LINE__,e,t)
_test_elem_innertext(unsigned line,IHTMLElement * elem,const char * extext)2680 static void _test_elem_innertext(unsigned line, IHTMLElement *elem, const char *extext)
2681 {
2682     BSTR text = NULL;
2683     HRESULT hres;
2684 
2685     hres = IHTMLElement_get_innerText(elem, &text);
2686     ok_(__FILE__,line) (hres == S_OK, "get_innerText failed: %08x\n", hres);
2687     if(extext)
2688         ok_(__FILE__,line) (!strcmp_wa(text, extext), "get_innerText returned %s expected %s\n",
2689                             wine_dbgstr_w(text), extext);
2690     else
2691         ok_(__FILE__,line) (!text, "get_innerText returned %s expected NULL\n", wine_dbgstr_w(text));
2692     SysFreeString(text);
2693 }
2694 
2695 #define test_elem_set_innertext(e,t) _test_elem_set_innertext(__LINE__,e,t)
_test_elem_set_innertext(unsigned line,IHTMLElement * elem,const char * text)2696 static void _test_elem_set_innertext(unsigned line, IHTMLElement *elem, const char *text)
2697 {
2698     IHTMLDOMChildrenCollection *col;
2699     BSTR str;
2700     HRESULT hres;
2701 
2702     str = a2bstr(text);
2703     hres = IHTMLElement_put_innerText(elem, str);
2704     ok_(__FILE__,line) (hres == S_OK, "put_innerText failed: %08x\n", hres);
2705     SysFreeString(str);
2706 
2707     _test_elem_innertext(line, elem, text);
2708 
2709 
2710     col = _get_child_nodes(line, (IUnknown*)elem);
2711     ok(col != NULL, "col == NULL\n");
2712     if(col) {
2713         LONG length = 0, type;
2714         IHTMLDOMNode *node;
2715 
2716         hres = IHTMLDOMChildrenCollection_get_length(col, &length);
2717         ok(hres == S_OK, "get_length failed: %08x\n", hres);
2718         ok(length == 1, "length = %d\n", length);
2719 
2720         node = _get_child_item(line, col, 0);
2721         ok(node != NULL, "node == NULL\n");
2722         if(node) {
2723             type = _get_node_type(line, (IUnknown*)node);
2724             ok(type == 3, "type=%d\n", type);
2725             IHTMLDOMNode_Release(node);
2726         }
2727 
2728         IHTMLDOMChildrenCollection_Release(col);
2729     }
2730 
2731 }
2732 
2733 #define test_elem_innerhtml(e,t) _test_elem_innerhtml(__LINE__,e,t)
_test_elem_innerhtml(unsigned line,IUnknown * unk,const char * inner_html)2734 static void _test_elem_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2735 {
2736     IHTMLElement *elem = _get_elem_iface(line, unk);
2737     BSTR html;
2738     HRESULT hres;
2739 
2740     hres = IHTMLElement_get_innerHTML(elem, &html);
2741     ok_(__FILE__,line)(hres == S_OK, "get_innerHTML failed: %08x\n", hres);
2742     if(inner_html)
2743         ok_(__FILE__,line)(!strcmp_wa(html, inner_html), "unexpected innerHTML: %s\n", wine_dbgstr_w(html));
2744     else
2745         ok_(__FILE__,line)(!html, "innerHTML = %s\n", wine_dbgstr_w(html));
2746 
2747     IHTMLElement_Release(elem);
2748     SysFreeString(html);
2749 }
2750 
2751 #define test_elem_set_innerhtml(e,t) _test_elem_set_innerhtml(__LINE__,e,t)
_test_elem_set_innerhtml(unsigned line,IUnknown * unk,const char * inner_html)2752 static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2753 {
2754     IHTMLElement *elem = _get_elem_iface(line, unk);
2755     BSTR html;
2756     HRESULT hres;
2757 
2758     html = a2bstr(inner_html);
2759     hres = IHTMLElement_put_innerHTML(elem, html);
2760     ok_(__FILE__,line)(hres == S_OK, "put_innerHTML failed: %08x\n", hres);
2761 
2762     IHTMLElement_Release(elem);
2763     SysFreeString(html);
2764 }
2765 
2766 #define test_elem_set_outerhtml(e,t) _test_elem_set_outerhtml(__LINE__,e,t)
_test_elem_set_outerhtml(unsigned line,IUnknown * unk,const char * outer_html)2767 static void _test_elem_set_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2768 {
2769     IHTMLElement *elem = _get_elem_iface(line, unk);
2770     BSTR html;
2771     HRESULT hres;
2772 
2773     html = a2bstr(outer_html);
2774     hres = IHTMLElement_put_outerHTML(elem, html);
2775     ok_(__FILE__,line)(hres == S_OK, "put_outerHTML failed: %08x\n", hres);
2776 
2777     IHTMLElement_Release(elem);
2778     SysFreeString(html);
2779 }
2780 
2781 #define test_elem_outerhtml(e,t) _test_elem_outerhtml(__LINE__,e,t)
_test_elem_outerhtml(unsigned line,IUnknown * unk,const char * outer_html)2782 static void _test_elem_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2783 {
2784     IHTMLElement *elem = _get_elem_iface(line, unk);
2785     BSTR html;
2786     HRESULT hres;
2787 
2788     hres = IHTMLElement_get_outerHTML(elem, &html);
2789     ok_(__FILE__,line)(hres == S_OK, "get_outerHTML failed: %08x\n", hres);
2790     ok_(__FILE__,line)(!strcmp_wa(html, outer_html), "outerHTML = '%s', expected '%s'\n", wine_dbgstr_w(html), outer_html);
2791 
2792     IHTMLElement_Release(elem);
2793     SysFreeString(html);
2794 }
2795 
2796 #define test_elem_contains(a,b,c) _test_elem_contains(__LINE__,a,b,c)
_test_elem_contains(unsigned line,IHTMLElement * elem,IHTMLElement * elem2,VARIANT_BOOL exval)2797 static void _test_elem_contains(unsigned line, IHTMLElement *elem, IHTMLElement *elem2, VARIANT_BOOL exval)
2798 {
2799     VARIANT_BOOL b;
2800     HRESULT hres;
2801 
2802     b = 100;
2803     hres = IHTMLElement_contains(elem, elem2, &b);
2804     ok_(__FILE__,line)(hres == S_OK, "contains failed: %08x\n", hres);
2805     ok_(__FILE__,line)(b == exval, "contains returned %x, expected %x\n", b, exval);
2806 }
2807 
2808 #define test_elem_istextedit(a,b) _test_elem_istextedit(__LINE__,a,b)
_test_elem_istextedit(unsigned line,IHTMLElement * elem,VARIANT_BOOL exval)2809 static void _test_elem_istextedit(unsigned line, IHTMLElement *elem, VARIANT_BOOL exval)
2810 {
2811     VARIANT_BOOL b;
2812     HRESULT hres;
2813 
2814     b = 100;
2815     hres = IHTMLElement_get_isTextEdit(elem, &b);
2816     ok_(__FILE__,line)(hres == S_OK, "isTextEdit failed: %08x\n", hres);
2817     ok_(__FILE__,line)(b == exval, "isTextEdit = %x\n", b);
2818 }
2819 
2820 #define get_first_child(n) _get_first_child(__LINE__,n)
_get_first_child(unsigned line,IUnknown * unk)2821 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
2822 {
2823     IHTMLDOMNode *node = _get_node_iface(line, unk);
2824     IHTMLDOMNode *child = NULL;
2825     HRESULT hres;
2826 
2827     hres = IHTMLDOMNode_get_firstChild(node, &child);
2828     IHTMLDOMNode_Release(node);
2829     ok_(__FILE__,line) (hres == S_OK, "get_firstChild failed: %08x\n", hres);
2830 
2831     return child;
2832 }
2833 
2834 #define test_node_has_child(u,b) _test_node_has_child(__LINE__,u,b)
_test_node_has_child(unsigned line,IUnknown * unk,VARIANT_BOOL exb)2835 static void _test_node_has_child(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2836 {
2837     IHTMLDOMNode *node = _get_node_iface(line, unk);
2838     VARIANT_BOOL b = 0xdead;
2839     HRESULT hres;
2840 
2841     hres = IHTMLDOMNode_hasChildNodes(node, &b);
2842     ok_(__FILE__,line) (hres == S_OK, "hasChildNodes failed: %08x\n", hres);
2843     ok_(__FILE__,line) (b == exb, "hasChildNodes=%x, expected %x\n", b, exb);
2844 
2845     IHTMLDOMNode_Release(node);
2846 }
2847 
2848 #define test_node_get_parent(u) _test_node_get_parent(__LINE__,u)
_test_node_get_parent(unsigned line,IUnknown * unk)2849 static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
2850 {
2851     IHTMLDOMNode *node = _get_node_iface(line, unk);
2852     IHTMLDOMNode *parent;
2853     HRESULT hres;
2854 
2855     hres = IHTMLDOMNode_get_parentNode(node, &parent);
2856     IHTMLDOMNode_Release(node);
2857     ok_(__FILE__,line) (hres == S_OK, "get_parentNode failed: %08x\n", hres);
2858 
2859     return parent;
2860 }
2861 
2862 #define node_get_next(u) _node_get_next(__LINE__,u)
_node_get_next(unsigned line,IUnknown * unk)2863 static IHTMLDOMNode *_node_get_next(unsigned line, IUnknown *unk)
2864 {
2865     IHTMLDOMNode *node = _get_node_iface(line, unk);
2866     IHTMLDOMNode *next;
2867     HRESULT hres;
2868 
2869     hres = IHTMLDOMNode_get_nextSibling(node, &next);
2870     IHTMLDOMNode_Release(node);
2871     ok_(__FILE__,line) (hres == S_OK, "get_nextSiblibg failed: %08x\n", hres);
2872 
2873     return next;
2874 }
2875 
2876 #define node_get_prev(u) _node_get_prev(__LINE__,u)
_node_get_prev(unsigned line,IUnknown * unk)2877 static IHTMLDOMNode *_node_get_prev(unsigned line, IUnknown *unk)
2878 {
2879     IHTMLDOMNode *node = _get_node_iface(line, unk);
2880     IHTMLDOMNode *prev;
2881     HRESULT hres;
2882 
2883     hres = IHTMLDOMNode_get_previousSibling(node, &prev);
2884     IHTMLDOMNode_Release(node);
2885     ok_(__FILE__,line) (hres == S_OK, "get_previousSibling failed: %08x\n", hres);
2886 
2887     return prev;
2888 }
2889 
2890 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
_test_elem_get_parent(unsigned line,IUnknown * unk)2891 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
2892 {
2893     IHTMLElement *elem = _get_elem_iface(line, unk);
2894     IHTMLElement *parent;
2895     HRESULT hres;
2896 
2897     hres = IHTMLElement_get_parentElement(elem, &parent);
2898     IHTMLElement_Release(elem);
2899     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
2900 
2901     return parent;
2902 }
2903 
2904 #define test_elem3_get_disabled(i,b) _test_elem3_get_disabled(__LINE__,i,b)
_test_elem3_get_disabled(unsigned line,IUnknown * unk,VARIANT_BOOL exb)2905 static void _test_elem3_get_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2906 {
2907     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2908     VARIANT_BOOL disabled = 100;
2909     HRESULT hres;
2910 
2911     if (!elem3) return;
2912     hres = IHTMLElement3_get_disabled(elem3, &disabled);
2913     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2914     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2915     IHTMLElement3_Release(elem3);
2916 }
2917 
2918 #define test_elem3_set_disabled(i,b) _test_elem3_set_disabled(__LINE__,i,b)
_test_elem3_set_disabled(unsigned line,IUnknown * unk,VARIANT_BOOL b)2919 static void _test_elem3_set_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL b)
2920 {
2921     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2922     HRESULT hres;
2923 
2924     if (!elem3) return;
2925     hres = IHTMLElement3_put_disabled(elem3, b);
2926     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2927 
2928     IHTMLElement3_Release(elem3);
2929     _test_elem3_get_disabled(line, unk, b);
2930 }
2931 
2932 #define test_select_get_disabled(i,b) _test_select_get_disabled(__LINE__,i,b)
_test_select_get_disabled(unsigned line,IHTMLSelectElement * select,VARIANT_BOOL exb)2933 static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exb)
2934 {
2935     VARIANT_BOOL disabled = 100;
2936     HRESULT hres;
2937 
2938     hres = IHTMLSelectElement_get_disabled(select, &disabled);
2939     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2940     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2941 
2942     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
2943 }
2944 
test_select_remove(IHTMLSelectElement * select)2945 static void test_select_remove(IHTMLSelectElement *select)
2946 {
2947     HRESULT hres;
2948 
2949     hres = IHTMLSelectElement_remove(select, 3);
2950     ok(hres == S_OK, "remove failed: %08x, expected S_OK\n", hres);
2951     test_select_length(select, 2);
2952 
2953     hres = IHTMLSelectElement_remove(select, -1);
2954     ok(hres == E_INVALIDARG, "remove failed: %08x, expected E_INVALIDARG\n", hres);
2955     test_select_length(select, 2);
2956 
2957     hres = IHTMLSelectElement_remove(select, 0);
2958     ok(hres == S_OK, "remove failed:%08x\n", hres);
2959     test_select_length(select, 1);
2960 }
2961 
2962 #define test_text_length(u,l) _test_text_length(__LINE__,u,l)
_test_text_length(unsigned line,IUnknown * unk,LONG l)2963 static void _test_text_length(unsigned line, IUnknown *unk, LONG l)
2964 {
2965     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2966     LONG length;
2967     HRESULT hres;
2968 
2969     hres = IHTMLDOMTextNode_get_length(text, &length);
2970     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
2971     ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l);
2972     IHTMLDOMTextNode_Release(text);
2973 }
2974 
2975 #define test_text_data(a,b) _test_text_data(__LINE__,a,b)
_test_text_data(unsigned line,IUnknown * unk,const char * exdata)2976 static void _test_text_data(unsigned line, IUnknown *unk, const char *exdata)
2977 {
2978     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2979     BSTR str;
2980     HRESULT hres;
2981 
2982     hres = IHTMLDOMTextNode_get_data(text, &str);
2983     ok_(__FILE__,line)(hres == S_OK, "get_data failed: %08x\n", hres);
2984     ok_(__FILE__,line)(!strcmp_wa(str, exdata), "data = %s, expected %s\n", wine_dbgstr_w(str), exdata);
2985     IHTMLDOMTextNode_Release(text);
2986     SysFreeString(str);
2987 }
2988 
2989 #define set_text_data(a,b) _set_text_data(__LINE__,a,b)
_set_text_data(unsigned line,IUnknown * unk,const char * data)2990 static void _set_text_data(unsigned line, IUnknown *unk, const char *data)
2991 {
2992     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2993     BSTR str = a2bstr(data);
2994     HRESULT hres;
2995 
2996     hres = IHTMLDOMTextNode_put_data(text, str);
2997     ok_(__FILE__,line)(hres == S_OK, "get_data failed: %08x\n", hres);
2998     IHTMLDOMTextNode_Release(text);
2999     SysFreeString(str);
3000 }
3001 
3002 #define text_append_data(a,b) _text_append_data(__LINE__,a,b)
_text_append_data(unsigned line,IUnknown * unk,const char * data)3003 static void _text_append_data(unsigned line, IUnknown *unk, const char *data)
3004 {
3005     IHTMLDOMTextNode2 *text = _get_text2_iface(line, unk);
3006     BSTR str = a2bstr(data);
3007     HRESULT hres;
3008 
3009     hres = IHTMLDOMTextNode2_appendData(text, str);
3010     ok_(__FILE__,line)(hres == S_OK, "appendData failed: %08x\n", hres);
3011     IHTMLDOMTextNode2_Release(text);
3012     SysFreeString(str);
3013 }
3014 
3015 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
_test_select_set_disabled(unsigned line,IHTMLSelectElement * select,VARIANT_BOOL b)3016 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
3017 {
3018     HRESULT hres;
3019 
3020     hres = IHTMLSelectElement_put_disabled(select, b);
3021     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
3022 
3023     _test_select_get_disabled(line, select, b);
3024 }
3025 
3026 #define test_elem_dir(u,n) _test_elem_dir(__LINE__,u,n)
_test_elem_dir(unsigned line,IUnknown * unk,const char * exdir)3027 static void _test_elem_dir(unsigned line, IUnknown *unk, const char *exdir)
3028 {
3029     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3030     BSTR dir;
3031     HRESULT hres;
3032 
3033     hres = IHTMLElement2_get_dir(elem, &dir);
3034     IHTMLElement2_Release(elem);
3035     ok_(__FILE__, line) (hres == S_OK, "get_dir failed: %08x\n", hres);
3036     if(exdir)
3037         ok_(__FILE__, line) (!strcmp_wa(dir, exdir), "got dir: %s, expected %s\n", wine_dbgstr_w(dir), exdir);
3038     else
3039         ok_(__FILE__, line) (!dir, "got dir: %s, expected NULL\n", wine_dbgstr_w(dir));
3040 
3041     SysFreeString(dir);
3042 }
3043 
3044 #define set_elem_dir(u,n) _set_elem_dir(__LINE__,u,n)
_set_elem_dir(unsigned line,IUnknown * unk,const char * dira)3045 static void _set_elem_dir(unsigned line, IUnknown *unk, const char *dira)
3046 {
3047     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3048     BSTR dir = a2bstr(dira);
3049     HRESULT hres;
3050 
3051     hres = IHTMLElement2_put_dir(elem, dir);
3052     IHTMLElement2_Release(elem);
3053     ok_(__FILE__, line) (hres == S_OK, "put_dir failed: %08x\n", hres);
3054     SysFreeString(dir);
3055 
3056     _test_elem_dir(line, unk, dira);
3057 }
3058 
3059 #define elem_get_scroll_height(u) _elem_get_scroll_height(__LINE__,u)
_elem_get_scroll_height(unsigned line,IUnknown * unk)3060 static LONG _elem_get_scroll_height(unsigned line, IUnknown *unk)
3061 {
3062     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3063     IHTMLTextContainer *txtcont;
3064     LONG l = -1, l2 = -1;
3065     HRESULT hres;
3066 
3067     hres = IHTMLElement2_get_scrollHeight(elem, &l);
3068     ok_(__FILE__,line) (hres == S_OK, "get_scrollHeight failed: %08x\n", hres);
3069     IHTMLElement2_Release(elem);
3070 
3071     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
3072     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
3073 
3074     hres = IHTMLTextContainer_get_scrollHeight(txtcont, &l2);
3075     IHTMLTextContainer_Release(txtcont);
3076     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollHeight failed: %d\n", l2);
3077     ok_(__FILE__,line) (l == l2, "unexpected height %d, expected %d\n", l2, l);
3078 
3079     return l;
3080 }
3081 
3082 #define elem_get_scroll_width(u) _elem_get_scroll_width(__LINE__,u)
_elem_get_scroll_width(unsigned line,IUnknown * unk)3083 static LONG _elem_get_scroll_width(unsigned line, IUnknown *unk)
3084 {
3085     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3086     IHTMLTextContainer *txtcont;
3087     LONG l = -1, l2 = -1;
3088     HRESULT hres;
3089 
3090     hres = IHTMLElement2_get_scrollWidth(elem, &l);
3091     ok_(__FILE__,line) (hres == S_OK, "get_scrollWidth failed: %08x\n", hres);
3092     IHTMLElement2_Release(elem);
3093 
3094     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
3095     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
3096 
3097     hres = IHTMLTextContainer_get_scrollWidth(txtcont, &l2);
3098     IHTMLTextContainer_Release(txtcont);
3099     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollWidth failed: %d\n", l2);
3100     ok_(__FILE__,line) (l == l2, "unexpected width %d, expected %d\n", l2, l);
3101 
3102     return l;
3103 }
3104 
3105 #define elem_get_scroll_top(u) _elem_get_scroll_top(__LINE__,u)
_elem_get_scroll_top(unsigned line,IUnknown * unk)3106 static LONG _elem_get_scroll_top(unsigned line, IUnknown *unk)
3107 {
3108     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3109     IHTMLTextContainer *txtcont;
3110     LONG l = -1, l2 = -1;
3111     HRESULT hres;
3112 
3113     hres = IHTMLElement2_get_scrollTop(elem, &l);
3114     ok_(__FILE__,line) (hres == S_OK, "get_scrollTop failed: %08x\n", hres);
3115     IHTMLElement2_Release(elem);
3116 
3117     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
3118     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
3119 
3120     hres = IHTMLTextContainer_get_scrollTop(txtcont, &l2);
3121     IHTMLTextContainer_Release(txtcont);
3122     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollTop failed: %d\n", l2);
3123     ok_(__FILE__,line) (l == l2, "unexpected top %d, expected %d\n", l2, l);
3124 
3125     return l;
3126 }
3127 
3128 #define elem_get_scroll_left(u) _elem_get_scroll_left(__LINE__,u)
_elem_get_scroll_left(unsigned line,IUnknown * unk)3129 static void _elem_get_scroll_left(unsigned line, IUnknown *unk)
3130 {
3131     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3132     IHTMLTextContainer *txtcont;
3133     LONG l = -1, l2 = -1;
3134     HRESULT hres;
3135 
3136     hres = IHTMLElement2_get_scrollLeft(elem, NULL);
3137     ok(hres == E_INVALIDARG, "expect E_INVALIDARG got 0x%08x\n", hres);
3138 
3139     hres = IHTMLElement2_get_scrollLeft(elem, &l);
3140     ok(hres == S_OK, "get_scrollTop failed: %08x\n", hres);
3141     IHTMLElement2_Release(elem);
3142 
3143     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
3144     ok(hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
3145 
3146     hres = IHTMLTextContainer_get_scrollLeft(txtcont, &l2);
3147     IHTMLTextContainer_Release(txtcont);
3148     ok(hres == S_OK, "IHTMLTextContainer::get_scrollLeft failed: %d\n", l2);
3149     ok(l == l2, "unexpected left %d, expected %d\n", l2, l);
3150 }
3151 
3152 #define test_img_src(a,b,c) _test_img_src(__LINE__,a,b,c)
_test_img_src(unsigned line,IUnknown * unk,const char * exsrc,const char * broken_src)3153 static void _test_img_src(unsigned line, IUnknown *unk, const char *exsrc, const char *broken_src)
3154 {
3155     IHTMLImgElement *img = _get_img_iface(line, unk);
3156     BSTR src;
3157     HRESULT hres;
3158 
3159     hres = IHTMLImgElement_get_src(img, &src);
3160     IHTMLImgElement_Release(img);
3161     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
3162     ok_(__FILE__,line) (!strcmp_wa(src, exsrc) || (broken_src && broken(!strcmp_wa(src, broken_src))),
3163         "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
3164     SysFreeString(src);
3165 }
3166 
3167 #define test_img_set_src(u,s) _test_img_set_src(__LINE__,u,s)
_test_img_set_src(unsigned line,IUnknown * unk,const char * src)3168 static void _test_img_set_src(unsigned line, IUnknown *unk, const char *src)
3169 {
3170     IHTMLImgElement *img = _get_img_iface(line, unk);
3171     BSTR tmp;
3172     HRESULT hres;
3173 
3174     tmp = a2bstr(src);
3175     hres = IHTMLImgElement_put_src(img, tmp);
3176     IHTMLImgElement_Release(img);
3177     SysFreeString(tmp);
3178     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
3179 }
3180 
3181 #define test_img_alt(u,a) _test_img_alt(__LINE__,u,a)
_test_img_alt(unsigned line,IUnknown * unk,const char * exalt)3182 static void _test_img_alt(unsigned line, IUnknown *unk, const char *exalt)
3183 {
3184     IHTMLImgElement *img = _get_img_iface(line, unk);
3185     BSTR alt;
3186     HRESULT hres;
3187 
3188     hres = IHTMLImgElement_get_alt(img, &alt);
3189     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
3190     if(exalt)
3191         ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "unexpected alt %s\n", wine_dbgstr_w(alt));
3192     else
3193         ok_(__FILE__,line) (!alt, "alt != NULL\n");
3194     SysFreeString(alt);
3195 }
3196 
3197 #define test_img_set_alt(u,a) _test_img_set_alt(__LINE__,u,a)
_test_img_set_alt(unsigned line,IUnknown * unk,const char * alt)3198 static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
3199 {
3200     IHTMLImgElement *img = _get_img_iface(line, unk);
3201     BSTR tmp;
3202     HRESULT hres;
3203 
3204     tmp = a2bstr(alt);
3205     hres = IHTMLImgElement_put_alt(img, tmp);
3206     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
3207     SysFreeString(tmp);
3208 
3209     _test_img_alt(line, unk, alt);
3210 }
3211 
3212 #define test_img_align(u,a) _test_img_align(__LINE__,u,a)
_test_img_align(unsigned line,IUnknown * unk,const char * align)3213 static void _test_img_align(unsigned line, IUnknown *unk, const char *align)
3214 {
3215     IHTMLImgElement *img = _get_img_iface(line, unk);
3216     BSTR tmp;
3217     HRESULT hres;
3218 
3219     tmp = a2bstr(align);
3220     hres = IHTMLImgElement_put_align(img, tmp);
3221     ok_(__FILE__,line) (hres == S_OK, "put_align failed: %08x\n", hres);
3222     SysFreeString(tmp);
3223 
3224     hres = IHTMLImgElement_get_align(img, &tmp);
3225     ok_(__FILE__,line) (hres == S_OK, "put_align failed: %08x\n", hres);
3226     ok_(__FILE__,line) (!strcmp_wa(tmp, align), "Expect %s, got %s\n", align, wine_dbgstr_w(tmp));
3227     SysFreeString(tmp);
3228 }
3229 
3230 #define test_img_name(u, c) _test_img_name(__LINE__,u, c)
_test_img_name(unsigned line,IUnknown * unk,const char * pValue)3231 static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue)
3232 {
3233     IHTMLImgElement *img = _get_img_iface(line, unk);
3234     BSTR sName;
3235     HRESULT hres;
3236 
3237     hres = IHTMLImgElement_get_name(img, &sName);
3238     ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres);
3239     ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName));
3240     IHTMLImgElement_Release(img);
3241     SysFreeString(sName);
3242 }
3243 
3244 #define test_img_complete(a,b) _test_img_complete(__LINE__,a,b)
_test_img_complete(unsigned line,IHTMLElement * elem,VARIANT_BOOL exb)3245 static void _test_img_complete(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
3246 {
3247     IHTMLImgElement *img = _get_img_iface(line, (IUnknown*)elem);
3248     VARIANT_BOOL b = 100;
3249     HRESULT hres;
3250 
3251     hres = IHTMLImgElement_get_complete(img, &b);
3252     ok_(__FILE__,line) (hres == S_OK, "get_complete failed: %08x\n", hres);
3253     ok_(__FILE__,line) (b == exb, "complete = %x, expected %x\n", b, exb);
3254     IHTMLImgElement_Release(img);
3255 }
3256 
3257 #define test_img_isMap(u, c) _test_img_isMap(__LINE__,u, c)
_test_img_isMap(unsigned line,IUnknown * unk,VARIANT_BOOL v)3258 static void _test_img_isMap(unsigned line, IUnknown *unk, VARIANT_BOOL v)
3259 {
3260     IHTMLImgElement *img = _get_img_iface(line, unk);
3261     VARIANT_BOOL b = 100;
3262     HRESULT hres;
3263 
3264     hres = IHTMLImgElement_put_isMap(img, v);
3265     ok_(__FILE__,line) (hres == S_OK, "put_isMap failed: %08x\n", hres);
3266 
3267     hres = IHTMLImgElement_get_isMap(img, &b);
3268     ok_(__FILE__,line) (hres == S_OK, "get_isMap failed: %08x\n", hres);
3269     ok_(__FILE__,line) (b == v, "isMap = %x, expected %x\n", b, v);
3270 
3271     hres = IHTMLImgElement_get_isMap(img, NULL);
3272     ok_(__FILE__,line) (hres == E_INVALIDARG, "ret = %08x, expected E_INVALIDARG\n", hres);
3273     IHTMLImgElement_Release(img);
3274 }
3275 
test_dynamic_properties(IHTMLElement * elem)3276 static void test_dynamic_properties(IHTMLElement *elem)
3277 {
3278     static const WCHAR attr1W[] = {'a','t','t','r','1',0};
3279     IDispatchEx *dispex;
3280     BSTR name, attr1 = SysAllocString(attr1W);
3281     VARIANT_BOOL succ;
3282     VARIANT val;
3283     int checked_no = 0;
3284     DISPID id = DISPID_STARTENUM;
3285     HRESULT hres;
3286 
3287     hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
3288     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
3289 
3290     hres = IHTMLElement_removeAttribute(elem, attr1, 0, &succ);
3291     ok(hres == S_OK, "removeAttribute failed: %08x\n", hres);
3292     ok(succ, "removeAttribute set succ to FALSE\n");
3293 
3294     while(1) {
3295         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, id, &id);
3296         ok(hres==S_OK || hres==S_FALSE, "GetNextDispID failed: %08x\n", hres);
3297         if(hres != S_OK)
3298             break;
3299 
3300         hres = IDispatchEx_GetMemberName(dispex, id, &name);
3301         ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
3302 
3303         if(!strcmp_wa(name, "attr1"))
3304             ok(0, "attr1 should be removed\n");
3305         else if(!strcmp_wa(name, "attr2") || !strcmp_wa(name, "attr3"))
3306             checked_no++;
3307         SysFreeString(name);
3308     }
3309     ok(checked_no == 2, "checked_no=%d, expected 2\n", checked_no);
3310     IDispatchEx_Release(dispex);
3311 
3312     V_VT(&val) = VT_BSTR;
3313     V_BSTR(&val) = attr1;
3314     hres = IHTMLElement_setAttribute(elem, attr1, val, 0);
3315     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
3316     SysFreeString(attr1);
3317 }
3318 
3319 #define test_attr_node_name(a,b) _test_attr_node_name(__LINE__,a,b)
_test_attr_node_name(unsigned line,IHTMLDOMAttribute * attr,const char * exname)3320 static void _test_attr_node_name(unsigned line, IHTMLDOMAttribute *attr, const char *exname)
3321 {
3322     BSTR str;
3323     HRESULT hres;
3324 
3325     hres = IHTMLDOMAttribute_get_nodeName(attr, &str);
3326     ok_(__FILE__,line)(hres == S_OK, "get_nodeName failed: %08x\n", hres);
3327     ok_(__FILE__,line)(!strcmp_wa(str, exname), "node name is %s, expected %s\n", wine_dbgstr_w(str), exname);
3328     SysFreeString(str);
3329 }
3330 
test_attr_collection_disp(IDispatch * disp)3331 static void test_attr_collection_disp(IDispatch *disp)
3332 {
3333     IDispatchEx *dispex;
3334     IHTMLDOMAttribute *attr;
3335     DISPPARAMS dp = {NULL, NULL, 0, 0};
3336     VARIANT var;
3337     EXCEPINFO ei;
3338     DISPID id;
3339     BSTR bstr;
3340     HRESULT hres;
3341 
3342     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
3343     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
3344 
3345     bstr = a2bstr("0");
3346     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
3347     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
3348     SysFreeString(bstr);
3349 
3350     VariantInit(&var);
3351     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
3352     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
3353     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
3354     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
3355     VariantClear(&var);
3356 
3357     bstr = a2bstr("attr1");
3358     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
3359     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
3360     SysFreeString(bstr);
3361 
3362     VariantInit(&var);
3363     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
3364     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
3365     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
3366     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
3367     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLDOMAttribute, (void**)&attr);
3368     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
3369 
3370     test_attr_node_name(attr, "attr1");
3371 
3372     IHTMLDOMAttribute_Release(attr);
3373     VariantClear(&var);
3374 
3375     IDispatchEx_Release(dispex);
3376 }
3377 
test_attr_collection(IHTMLElement * elem)3378 static void test_attr_collection(IHTMLElement *elem)
3379 {
3380     static const WCHAR testW[] = {'t','e','s','t',0};
3381 
3382     IHTMLDOMNode *node;
3383     IDispatch *disp, *attr;
3384     IHTMLDOMAttribute *dom_attr;
3385     IHTMLAttributeCollection *attr_col;
3386     BSTR name = SysAllocString(testW);
3387     VARIANT id, val;
3388     LONG i, len, checked;
3389     HRESULT hres;
3390 
3391     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLDOMNode, (void**)&node);
3392     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
3393 
3394     hres = IHTMLDOMNode_get_attributes(node, &disp);
3395     ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
3396 
3397     hres = IHTMLDOMNode_get_attributes(node, &attr);
3398     ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
3399     ok(iface_cmp((IUnknown*)disp, (IUnknown*)attr), "disp != attr\n");
3400     IDispatch_Release(attr);
3401     IHTMLDOMNode_Release(node);
3402 
3403     hres = IDispatch_QueryInterface(disp, &IID_IHTMLAttributeCollection, (void**)&attr_col);
3404     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
3405 
3406     hres = IHTMLAttributeCollection_get_length(attr_col, &i);
3407     ok(hres == S_OK, "get_length failed: %08x\n", hres);
3408 
3409     V_VT(&val) = VT_I4;
3410     V_I4(&val) = 1;
3411     hres = IHTMLElement_setAttribute(elem, name, val, 0);
3412     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
3413     SysFreeString(name);
3414 
3415     hres = IHTMLAttributeCollection_get_length(attr_col, &len);
3416     ok(hres == S_OK, "get_length failed: %08x\n", hres);
3417     ok(len == i+1, "get_length returned %d, expected %d\n", len, i+1);
3418 
3419     checked = 0;
3420     for(i=0; i<len; i++) {
3421         V_VT(&id) = VT_I4;
3422         V_I4(&id) = i;
3423         hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
3424         ok(hres == S_OK, "%d) item failed: %08x\n", i, hres);
3425 
3426         hres = IDispatch_QueryInterface(attr, &IID_IHTMLDOMAttribute, (void**)&dom_attr);
3427         ok(hres == S_OK, "%d) QueryInterface failed: %08x\n", i, hres);
3428         IDispatch_Release(attr);
3429 
3430         hres = IHTMLDOMAttribute_get_nodeName(dom_attr, &name);
3431         ok(hres == S_OK, "%d) get_nodeName failed: %08x\n", i, hres);
3432 
3433         if(!strcmp_wa(name, "id")) {
3434             checked++;
3435             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
3436             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
3437             ok(V_VT(&val) == VT_BSTR, "id: V_VT(&val) = %d\n", V_VT(&val));
3438             ok(!strcmp_wa(V_BSTR(&val), "attr"), "id: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
3439             test_attr_expando(dom_attr, VARIANT_FALSE);
3440             test_attr_value(dom_attr, "attr");
3441         } else if(!strcmp_wa(name, "attr1")) {
3442             checked++;
3443             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
3444             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
3445             ok(V_VT(&val) == VT_BSTR, "attr1: V_VT(&val) = %d\n", V_VT(&val));
3446             ok(!strcmp_wa(V_BSTR(&val), "attr1"), "attr1: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
3447             test_attr_expando(dom_attr, VARIANT_TRUE);
3448             test_attr_value(dom_attr, "attr1");
3449         } else if(!strcmp_wa(name, "attr2")) {
3450             checked++;
3451             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
3452             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
3453             ok(V_VT(&val) == VT_BSTR, "attr2: V_VT(&val) = %d\n", V_VT(&val));
3454             ok(!V_BSTR(&val), "attr2: V_BSTR(&val) != NULL\n");
3455             test_attr_value(dom_attr, "");
3456         } else if(!strcmp_wa(name, "attr3")) {
3457             checked++;
3458             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
3459             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
3460             ok(V_VT(&val) == VT_BSTR, "attr3: V_VT(&val) = %d\n", V_VT(&val));
3461             ok(!strcmp_wa(V_BSTR(&val), "attr3"), "attr3: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
3462             test_attr_value(dom_attr, "attr3");
3463         } else if(!strcmp_wa(name, "test")) {
3464             checked++;
3465             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
3466             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
3467             ok(V_VT(&val) == VT_I4, "test: V_VT(&val) = %d\n", V_VT(&val));
3468             ok(V_I4(&val) == 1, "test: V_I4(&val) = %d\n", V_I4(&val));
3469             test_attr_value(dom_attr, "1");
3470         }
3471 
3472         IHTMLDOMAttribute_Release(dom_attr);
3473         SysFreeString(name);
3474         VariantClear(&val);
3475     }
3476     ok(checked==5, "invalid number of specified attributes (%d)\n", checked);
3477 
3478     V_I4(&id) = len;
3479     hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
3480     ok(hres == E_INVALIDARG, "item failed: %08x\n", hres);
3481 
3482     V_VT(&id) = VT_BSTR;
3483     V_BSTR(&id) = a2bstr("nonexisting");
3484     hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
3485     ok(hres == E_INVALIDARG, "item failed: %08x\n", hres);
3486     VariantClear(&id);
3487 
3488     test_attr_collection_disp(disp);
3489 
3490     IDispatch_Release(disp);
3491     IHTMLAttributeCollection_Release(attr_col);
3492 }
3493 
3494 #define test_elem_id(e,i) _test_elem_id(__LINE__,e,i)
_test_elem_id(unsigned line,IUnknown * unk,const char * exid)3495 static void _test_elem_id(unsigned line, IUnknown *unk, const char *exid)
3496 {
3497     IHTMLElement *elem = _get_elem_iface(line, unk);
3498     BSTR id = (void*)0xdeadbeef;
3499     HRESULT hres;
3500 
3501     hres = IHTMLElement_get_id(elem, &id);
3502     IHTMLElement_Release(elem);
3503     ok_(__FILE__,line) (hres == S_OK, "get_id failed: %08x\n", hres);
3504 
3505     if(exid)
3506         ok_(__FILE__,line) (!strcmp_wa(id, exid), "unexpected id %s\n", wine_dbgstr_w(id));
3507     else
3508         ok_(__FILE__,line) (!id, "id=%s\n", wine_dbgstr_w(id));
3509 
3510     SysFreeString(id);
3511 }
3512 
3513 #define test_elem_language(e,i) _test_elem_language(__LINE__,e,i)
_test_elem_language(unsigned line,IHTMLElement * elem,const char * exlang)3514 static void _test_elem_language(unsigned line, IHTMLElement *elem, const char *exlang)
3515 {
3516     BSTR lang = (void*)0xdeadbeef;
3517     HRESULT hres;
3518 
3519     hres = IHTMLElement_get_language(elem, &lang);
3520     ok_(__FILE__,line) (hres == S_OK, "get_language failed: %08x\n", hres);
3521 
3522     if(exlang)
3523         ok_(__FILE__,line) (!strcmp_wa(lang, exlang), "unexpected language %s\n", wine_dbgstr_w(lang));
3524     else
3525         ok_(__FILE__,line) (!lang, "language=%s\n", wine_dbgstr_w(lang));
3526 
3527     SysFreeString(lang);
3528 }
3529 
3530 #define set_elem_language(e,i) _set_elem_language(__LINE__,e,i)
_set_elem_language(unsigned line,IHTMLElement * elem,const char * lang)3531 static void _set_elem_language(unsigned line, IHTMLElement *elem, const char *lang)
3532 {
3533     BSTR str = a2bstr(lang);
3534     HRESULT hres;
3535 
3536     hres = IHTMLElement_put_language(elem, str);
3537     ok_(__FILE__,line) (hres == S_OK, "get_language failed: %08x\n", hres);
3538     SysFreeString(str);
3539 
3540     _test_elem_language(line, elem, lang);
3541 }
3542 
3543 #define test_elem_put_id(u,i) _test_elem_put_id(__LINE__,u,i)
_test_elem_put_id(unsigned line,IUnknown * unk,const char * new_id)3544 static void _test_elem_put_id(unsigned line, IUnknown *unk, const char *new_id)
3545 {
3546     IHTMLElement *elem = _get_elem_iface(line, unk);
3547     BSTR tmp = a2bstr(new_id);
3548     HRESULT hres;
3549 
3550     hres = IHTMLElement_put_id(elem, tmp);
3551     IHTMLElement_Release(elem);
3552     SysFreeString(tmp);
3553     ok_(__FILE__,line) (hres == S_OK, "put_id failed: %08x\n", hres);
3554 
3555     _test_elem_id(line, unk, new_id);
3556 }
3557 
test_contenteditable(IUnknown * unk)3558 static void test_contenteditable(IUnknown *unk)
3559 {
3560     IHTMLElement3 *elem3 = get_elem3_iface(unk);
3561     HRESULT hres;
3562     BSTR str, strDefault;
3563 
3564     hres = IHTMLElement3_get_contentEditable(elem3, &strDefault);
3565     ok(hres == S_OK, "get_contentEditable failed: 0x%08x\n", hres);
3566 
3567     str = a2bstr("true");
3568     hres = IHTMLElement3_put_contentEditable(elem3, str);
3569     ok(hres == S_OK, "put_contentEditable(%s) failed: 0x%08x\n", wine_dbgstr_w(str), hres);
3570     SysFreeString(str);
3571     hres = IHTMLElement3_get_contentEditable(elem3, &str);
3572     ok(hres == S_OK, "get_contentEditable failed: 0x%08x\n", hres);
3573     ok(!strcmp_wa(str, "true"), "Got %s, expected %s\n", wine_dbgstr_w(str), "true");
3574 
3575     /* Restore origin contentEditable */
3576     hres = IHTMLElement3_put_contentEditable(elem3, strDefault);
3577     ok(hres == S_OK, "put_contentEditable(%s) failed: 0x%08x\n", wine_dbgstr_w(strDefault), hres);
3578     SysFreeString(strDefault);
3579 
3580     IHTMLElement3_Release(elem3);
3581 }
3582 
3583 #define test_input_type(i,t) _test_input_type(__LINE__,i,t)
_test_input_type(unsigned line,IHTMLInputElement * input,const char * extype)3584 static void _test_input_type(unsigned line, IHTMLInputElement *input, const char *extype)
3585 {
3586     BSTR type;
3587     HRESULT hres;
3588 
3589     hres = IHTMLInputElement_get_type(input, &type);
3590     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
3591     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
3592     SysFreeString(type);
3593 }
3594 
3595 #define test_input_name(u, c) _test_input_name(__LINE__,u, c)
_test_input_name(unsigned line,IHTMLInputElement * input,const char * exname)3596 static void _test_input_name(unsigned line, IHTMLInputElement *input, const char *exname)
3597 {
3598     BSTR name = (BSTR)0xdeadbeef;
3599     HRESULT hres;
3600 
3601     hres = IHTMLInputElement_get_name(input, &name);
3602     ok_(__FILE__,line) (hres == S_OK, "get_name failed: %08x\n", hres);
3603     if(exname)
3604         ok_(__FILE__,line) (!strcmp_wa (name, exname), "name=%s, expected %s\n", wine_dbgstr_w(name), exname);
3605     else
3606         ok_(__FILE__,line) (!name, "name=%p, expected NULL\n", name);
3607     SysFreeString(name);
3608 }
3609 
3610 #define test_input_set_name(u, c) _test_input_set_name(__LINE__,u, c)
_test_input_set_name(unsigned line,IHTMLInputElement * input,const char * name)3611 static void _test_input_set_name(unsigned line, IHTMLInputElement *input, const char *name)
3612 {
3613     BSTR tmp = a2bstr(name);
3614     HRESULT hres;
3615 
3616     hres = IHTMLInputElement_put_name(input, tmp);
3617     ok_(__FILE__,line) (hres == S_OK, "put_name failed: %08x\n", hres);
3618     SysFreeString(tmp);
3619 
3620     _test_input_name(line, input, name);
3621 }
3622 
3623 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
_test_input_get_disabled(unsigned line,IHTMLInputElement * input,VARIANT_BOOL exb)3624 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
3625 {
3626     VARIANT_BOOL disabled = 100;
3627     HRESULT hres;
3628 
3629     hres = IHTMLInputElement_get_disabled(input, &disabled);
3630     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
3631     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
3632 
3633     _test_elem3_get_disabled(line, (IUnknown*)input, exb);
3634 }
3635 
3636 #define test_input_set_disabled(i,b) _test_input_set_disabled(__LINE__,i,b)
_test_input_set_disabled(unsigned line,IHTMLInputElement * input,VARIANT_BOOL b)3637 static void _test_input_set_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
3638 {
3639     HRESULT hres;
3640 
3641     hres = IHTMLInputElement_put_disabled(input, b);
3642     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
3643 
3644     _test_input_get_disabled(line, input, b);
3645 }
3646 
3647 #define test_input_get_defaultchecked(i,b) _test_input_get_defaultchecked(__LINE__,i,b)
_test_input_get_defaultchecked(unsigned line,IHTMLInputElement * input,VARIANT_BOOL exb)3648 static void _test_input_get_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
3649 {
3650     VARIANT_BOOL checked = 100;
3651     HRESULT hres;
3652 
3653     hres = IHTMLInputElement_get_defaultChecked(input, &checked);
3654     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
3655     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
3656 }
3657 
3658 #define test_input_set_defaultchecked(i,b) _test_input_set_defaultchecked(__LINE__,i,b)
_test_input_set_defaultchecked(unsigned line,IHTMLInputElement * input,VARIANT_BOOL b)3659 static void _test_input_set_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
3660 {
3661     HRESULT hres;
3662 
3663     hres = IHTMLInputElement_put_defaultChecked(input, b);
3664     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
3665 
3666     _test_input_get_defaultchecked(line, input, b);
3667 }
3668 
3669 #define test_input_get_checked(i,b) _test_input_get_checked(__LINE__,i,b)
_test_input_get_checked(unsigned line,IHTMLInputElement * input,VARIANT_BOOL exb)3670 static void _test_input_get_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
3671 {
3672     VARIANT_BOOL checked = 100;
3673     HRESULT hres;
3674 
3675     hres = IHTMLInputElement_get_checked(input, &checked);
3676     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
3677     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
3678 }
3679 
3680 #define test_input_set_checked(i,b) _test_input_set_checked(__LINE__,i,b)
_test_input_set_checked(unsigned line,IHTMLInputElement * input,VARIANT_BOOL b)3681 static void _test_input_set_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
3682 {
3683     HRESULT hres;
3684 
3685     hres = IHTMLInputElement_put_checked(input, b);
3686     ok_(__FILE__,line) (hres == S_OK, "put_checked failed: %08x\n", hres);
3687 
3688     _test_input_get_checked(line, input, b);
3689 }
3690 
3691 #define test_input_maxlength(i,b) _test_input_maxlength(__LINE__,i,b)
_test_input_maxlength(unsigned line,IHTMLInputElement * input,LONG exl)3692 static void _test_input_maxlength(unsigned line, IHTMLInputElement *input, LONG exl)
3693 {
3694     LONG maxlength = 0xdeadbeef;
3695     HRESULT hres;
3696 
3697     hres = IHTMLInputElement_get_maxLength(input, &maxlength);
3698     ok_(__FILE__,line) (hres == S_OK, "get_maxLength failed: %08x\n", hres);
3699     ok_(__FILE__,line) (maxlength == exl, "maxLength=%x, expected %d\n", maxlength, exl);
3700 }
3701 
3702 #define test_input_set_maxlength(i,b) _test_input_set_maxlength(__LINE__,i,b)
_test_input_set_maxlength(unsigned line,IHTMLInputElement * input,LONG l)3703 static void _test_input_set_maxlength(unsigned line, IHTMLInputElement *input, LONG l)
3704 {
3705     HRESULT hres;
3706 
3707     hres = IHTMLInputElement_put_maxLength(input, l);
3708     ok_(__FILE__,line) (hres == S_OK, "put_maxLength failed: %08x\n", hres);
3709 
3710     _test_input_maxlength(line, input, l);
3711 }
3712 
3713 #define test_input_value(o,t) _test_input_value(__LINE__,o,t)
_test_input_value(unsigned line,IUnknown * unk,const char * exval)3714 static void _test_input_value(unsigned line, IUnknown *unk, const char *exval)
3715 {
3716     IHTMLInputElement *input;
3717     BSTR bstr;
3718     HRESULT hres;
3719 
3720     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3721     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3722     if(FAILED(hres))
3723         return;
3724 
3725     hres = IHTMLInputElement_get_value(input, &bstr);
3726     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
3727     if(exval)
3728         ok_(__FILE__,line) (!strcmp_wa(bstr, exval), "value=%s\n", wine_dbgstr_w(bstr));
3729     else
3730         ok_(__FILE__,line) (!bstr, "exval != NULL\n");
3731     SysFreeString(bstr);
3732     IHTMLInputElement_Release(input);
3733 }
3734 
3735 #define test_input_get_form(o, t)  _test_input_get_form(__LINE__, o, t)
_test_input_get_form(unsigned line,IUnknown * unk,const char * id)3736 static void _test_input_get_form(unsigned line, IUnknown *unk, const char *id)
3737 {
3738     IHTMLInputElement *input;
3739     IHTMLFormElement *form;
3740     IHTMLElement *elem;
3741     HRESULT hres;
3742 
3743     ok_(__FILE__,line) (unk != NULL, "unk is NULL!\n");
3744     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3745     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3746     ok_(__FILE__,line) (input != NULL, "input == NULL\n");
3747     if(FAILED(hres) || input == NULL)
3748         return;
3749 
3750     hres = IHTMLInputElement_get_form(input, &form);
3751     ok_(__FILE__, line) (hres == S_OK, "get_form failed: %08x\n", hres);
3752     ok_(__FILE__, line) (form != NULL, "form == NULL\n");
3753     if(FAILED(hres) || form == NULL){
3754         IHTMLInputElement_Release(input);
3755         return;
3756     }
3757 
3758     hres = IHTMLFormElement_QueryInterface(form, &IID_IHTMLElement, (void **)&elem);
3759     ok_(__FILE__, line) (hres == S_OK, "QueryInterface(IID_IHTMLElement) failed: %08x\n", hres);
3760     ok_(__FILE__, line) (elem != NULL, "elem == NULL\n");
3761     if(FAILED(hres) || elem == NULL){
3762         IHTMLInputElement_Release(input);
3763         IHTMLFormElement_Release(form);
3764         return;
3765     }
3766 
3767     _test_elem_id(line, (IUnknown*)elem, id);
3768 
3769     IHTMLInputElement_Release(input);
3770     IHTMLFormElement_Release(form);
3771     IHTMLElement_Release(elem);
3772 }
3773 
3774 #define test_input_put_value(o,v) _test_input_put_value(__LINE__,o,v)
_test_input_put_value(unsigned line,IUnknown * unk,const char * val)3775 static void _test_input_put_value(unsigned line, IUnknown *unk, const char *val)
3776 {
3777     IHTMLInputElement *input;
3778     BSTR bstr;
3779     HRESULT hres;
3780 
3781     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3782     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3783     if(FAILED(hres))
3784         return;
3785 
3786     bstr = a2bstr(val);
3787     hres = IHTMLInputElement_put_value(input, bstr);
3788     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
3789     SysFreeString(bstr);
3790     IHTMLInputElement_Release(input);
3791 
3792     _test_input_value(line, unk, val);
3793 }
3794 
3795 #define test_input_defaultValue(o,t) _test_input_defaultValue(__LINE__,o,t)
_test_input_defaultValue(unsigned line,IUnknown * unk,const char * exval)3796 static void _test_input_defaultValue(unsigned line, IUnknown *unk, const char *exval)
3797 {
3798     IHTMLInputElement *input;
3799     BSTR str;
3800     HRESULT hres;
3801 
3802     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3803     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3804     if(FAILED(hres))
3805         return;
3806 
3807     hres = IHTMLInputElement_get_defaultValue(input, &str);
3808     ok_(__FILE__,line) (hres == S_OK, "get_defaultValue failed: %08x\n", hres);
3809     if(exval)
3810         ok_(__FILE__,line) (!strcmp_wa(str, exval), "defaultValue=%s\n", wine_dbgstr_w(str));
3811     else
3812         ok_(__FILE__,line) (!str, "exval != NULL\n");
3813     SysFreeString(str);
3814     IHTMLInputElement_Release(input);
3815 }
3816 
3817 #define test_input_put_defaultValue(o,v) _test_input_put_defaultValue(__LINE__,o,v)
_test_input_put_defaultValue(unsigned line,IUnknown * unk,const char * val)3818 static void _test_input_put_defaultValue(unsigned line, IUnknown *unk, const char *val)
3819 {
3820     IHTMLInputElement *input;
3821     BSTR str;
3822     HRESULT hres;
3823 
3824     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
3825     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
3826     if(FAILED(hres))
3827         return;
3828 
3829     str = a2bstr(val);
3830     hres = IHTMLInputElement_put_defaultValue(input, str);
3831     ok_(__FILE__,line) (hres == S_OK, "get_defaultValue failed: %08x\n", hres);
3832     SysFreeString(str);
3833     IHTMLInputElement_Release(input);
3834 
3835     _test_input_defaultValue(line, unk, val);
3836 }
3837 
3838 #define test_input_src(i,s) _test_input_src(__LINE__,i,s)
_test_input_src(unsigned line,IHTMLInputElement * input,const char * exsrc)3839 static void _test_input_src(unsigned line, IHTMLInputElement *input, const char *exsrc)
3840 {
3841     BSTR src;
3842     HRESULT hres;
3843 
3844     hres = IHTMLInputElement_get_src(input, &src);
3845     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
3846     if(exsrc)
3847         ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
3848     else
3849         ok_(__FILE__,line) (!src, "get_src returned %s expected NULL\n", wine_dbgstr_w(src));
3850     SysFreeString(src);
3851 }
3852 
3853 #define test_input_set_src(u,s) _test_input_set_src(__LINE__,u,s)
_test_input_set_src(unsigned line,IHTMLInputElement * input,const char * src)3854 static void _test_input_set_src(unsigned line, IHTMLInputElement *input, const char *src)
3855 {
3856     BSTR tmp;
3857     HRESULT hres;
3858 
3859     tmp = a2bstr(src);
3860     hres = IHTMLInputElement_put_src(input, tmp);
3861     SysFreeString(tmp);
3862     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
3863 
3864     _test_input_src(line, input, src);
3865 }
3866 
3867 #define test_input_set_size(u,s,r) _test_input_set_size(__LINE__,u,s,r)
_test_input_set_size(unsigned line,IHTMLInputElement * input,LONG size,HRESULT exret)3868 static void _test_input_set_size(unsigned line, IHTMLInputElement *input, LONG size, HRESULT exret)
3869 {
3870     HRESULT hres;
3871 
3872     hres = IHTMLInputElement_put_size(input, size);
3873     ok_(__FILE__,line) (hres == exret, "Expect ret = %08x, got: %08x\n", exret, hres);
3874 }
3875 
3876 #define test_input_get_size(u,s) _test_input_get_size(__LINE__,u,s)
_test_input_get_size(unsigned line,IHTMLInputElement * input,LONG exsize)3877 static void _test_input_get_size(unsigned line, IHTMLInputElement *input, LONG exsize)
3878 {
3879     HRESULT hres;
3880     LONG size;
3881 
3882     hres = IHTMLInputElement_get_size(input, &size);
3883     ok_(__FILE__,line) (hres == S_OK, "get_size failed: %08x\n", hres);
3884     ok_(__FILE__,line) (size == exsize, "Expect %d, got %d\n", exsize, size);
3885 
3886     hres = IHTMLInputElement_get_size(input, NULL);
3887     ok_(__FILE__,line) (hres == E_INVALIDARG, "Expect ret E_INVALIDARG, got: %08x\n", hres);
3888 }
3889 
3890 #define test_input_readOnly(u,b) _test_input_readOnly(__LINE__,u,b)
_test_input_readOnly(unsigned line,IHTMLInputElement * input,VARIANT_BOOL v)3891 static void _test_input_readOnly(unsigned line, IHTMLInputElement *input, VARIANT_BOOL v)
3892 {
3893     HRESULT hres;
3894     VARIANT_BOOL b = 100;
3895 
3896     hres = IHTMLInputElement_put_readOnly(input, v);
3897     ok_(__FILE__,line)(hres == S_OK, "put readOnly failed: %08x\n", hres);
3898 
3899     hres = IHTMLInputElement_get_readOnly(input, &b);
3900     ok_(__FILE__,line)(hres == S_OK, "get readOnly failed: %08x\n", hres);
3901     ok_(__FILE__,line)(v == b, "Expect %x, got %x\n", v, b);
3902 }
3903 
3904 #define test_elem_class(u,c) _test_elem_class(__LINE__,u,c)
_test_elem_class(unsigned line,IUnknown * unk,const char * exclass)3905 static void _test_elem_class(unsigned line, IUnknown *unk, const char *exclass)
3906 {
3907     IHTMLElement *elem = _get_elem_iface(line, unk);
3908     BSTR class = (void*)0xdeadbeef;
3909     HRESULT hres;
3910 
3911     hres = IHTMLElement_get_className(elem, &class);
3912     IHTMLElement_Release(elem);
3913     ok_(__FILE__,line) (hres == S_OK, "get_className failed: %08x\n", hres);
3914     if(exclass)
3915         ok_(__FILE__,line) (!strcmp_wa(class, exclass), "unexpected className %s\n", wine_dbgstr_w(class));
3916     else
3917         ok_(__FILE__,line) (!class, "class != NULL\n");
3918     SysFreeString(class);
3919 }
3920 
3921 #define test_elem_tabindex(u,i) _test_elem_tabindex(__LINE__,u,i)
_test_elem_tabindex(unsigned line,IUnknown * unk,short exindex)3922 static void _test_elem_tabindex(unsigned line, IUnknown *unk, short exindex)
3923 {
3924     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
3925     short index = -3;
3926     HRESULT hres;
3927 
3928     hres = IHTMLElement2_get_tabIndex(elem2, &index);
3929     IHTMLElement2_Release(elem2);
3930     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
3931     ok_(__FILE__,line) (index == exindex, "unexpected index %d\n", index);
3932 }
3933 
3934 #define test_elem_set_tabindex(u,i) _test_elem_set_tabindex(__LINE__,u,i)
_test_elem_set_tabindex(unsigned line,IUnknown * unk,short index)3935 static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index)
3936 {
3937     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
3938     HRESULT hres;
3939 
3940     hres = IHTMLElement2_put_tabIndex(elem2, index);
3941     IHTMLElement2_Release(elem2);
3942     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
3943 
3944     _test_elem_tabindex(line, unk, index);
3945 }
3946 
3947 #define test_style_media(s,m) _test_style_media(__LINE__,s,m)
_test_style_media(unsigned line,IUnknown * unk,const char * exmedia)3948 static void _test_style_media(unsigned line, IUnknown *unk, const char *exmedia)
3949 {
3950     IHTMLStyleElement *style = _get_style_iface(line, unk);
3951     BSTR media;
3952     HRESULT hres;
3953 
3954     hres = IHTMLStyleElement_get_media(style, &media);
3955     ok_(__FILE__,line)(hres == S_OK, "get_media failed: %08x\n", hres);
3956     if(exmedia)
3957         ok_(__FILE__,line)(!strcmp_wa(media, exmedia), "media = %s, expected %s\n", wine_dbgstr_w(media), exmedia);
3958     else
3959         ok_(__FILE__,line)(!media, "media = %s, expected NULL\n", wine_dbgstr_w(media));
3960 
3961     IHTMLStyleElement_Release(style);
3962     SysFreeString(media);
3963 }
3964 
3965 #define test_style_put_media(s,m) _test_style_put_media(__LINE__,s,m)
_test_style_put_media(unsigned line,IUnknown * unk,const char * media)3966 static void _test_style_put_media(unsigned line, IUnknown *unk, const char *media)
3967 {
3968     IHTMLStyleElement *style = _get_style_iface(line, unk);
3969     BSTR str;
3970     HRESULT hres;
3971 
3972     str = a2bstr(media);
3973     hres = IHTMLStyleElement_put_media(style, str);
3974     ok_(__FILE__,line)(hres == S_OK, "put_media failed: %08x\n", hres);
3975     IHTMLStyleElement_Release(style);
3976     SysFreeString(str);
3977 
3978     _test_style_media(line, unk, media);
3979 }
3980 
3981 #define test_style_type(s,m) _test_style_type(__LINE__,s,m)
_test_style_type(unsigned line,IUnknown * unk,const char * extype)3982 static void _test_style_type(unsigned line, IUnknown *unk, const char *extype)
3983 {
3984     IHTMLStyleElement *style = _get_style_iface(line, unk);
3985     BSTR type;
3986     HRESULT hres;
3987 
3988     hres = IHTMLStyleElement_get_type(style, &type);
3989     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
3990     if(extype)
3991         ok_(__FILE__,line)(!strcmp_wa(type, extype), "type = %s, expected %s\n", wine_dbgstr_w(type), extype);
3992     else
3993         ok_(__FILE__,line)(!type, "type = %s, expected NULL\n", wine_dbgstr_w(type));
3994 
3995     IHTMLStyleElement_Release(style);
3996     SysFreeString(type);
3997 }
3998 
3999 #define test_style_put_type(s,m) _test_style_put_type(__LINE__,s,m)
_test_style_put_type(unsigned line,IUnknown * unk,const char * type)4000 static void _test_style_put_type(unsigned line, IUnknown *unk, const char *type)
4001 {
4002     IHTMLStyleElement *style = _get_style_iface(line, unk);
4003     BSTR str;
4004     HRESULT hres;
4005 
4006     str = a2bstr(type);
4007     hres = IHTMLStyleElement_put_type(style, str);
4008     ok_(__FILE__,line)(hres == S_OK, "put_type failed: %08x\n", hres);
4009     IHTMLStyleElement_Release(style);
4010     SysFreeString(str);
4011 
4012     _test_style_type(line, unk, type);
4013 }
4014 
4015 #define test_elem_filters(u) _test_elem_filters(__LINE__,u)
_test_elem_filters(unsigned line,IUnknown * unk)4016 static void _test_elem_filters(unsigned line, IUnknown *unk)
4017 {
4018     IHTMLElement *elem = _get_elem_iface(line, unk);
4019     HRESULT hres;
4020     IHTMLFiltersCollection *filters;
4021 
4022     hres = IHTMLElement_get_filters(elem, &filters);
4023     ok_(__FILE__,line) (hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG) /* NT4 */,
4024                         "get_filters failed: %08x\n", hres);
4025     if(hres == S_OK)
4026     {
4027         LONG len;
4028         IDispatchEx *dispex;
4029 
4030         hres = IHTMLFiltersCollection_get_length(filters, &len);
4031         ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
4032         ok_(__FILE__,line) (len == 0, "expect 0 got %d\n", len);
4033 
4034         hres = IHTMLFiltersCollection_QueryInterface(filters, &IID_IDispatchEx, (void**)&dispex);
4035         ok_(__FILE__,line) (hres == S_OK || broken(hres == E_NOINTERFACE),
4036                             "Could not get IDispatchEx interface: %08x\n", hres);
4037         if(SUCCEEDED(hres)) {
4038             test_disp((IUnknown*)filters, &IID_IHTMLFiltersCollection, "[object]");
4039             IDispatchEx_Release(dispex);
4040         }
4041 
4042         IHTMLFiltersCollection_Release(filters);
4043     }
4044 
4045     IHTMLElement_Release(elem);
4046 }
4047 
4048 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
_test_elem_set_class(unsigned line,IUnknown * unk,const char * class)4049 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
4050 {
4051     IHTMLElement *elem = _get_elem_iface(line, unk);
4052     BSTR tmp;
4053     HRESULT hres;
4054 
4055     tmp = class ? a2bstr(class) : NULL;
4056     hres = IHTMLElement_put_className(elem, tmp);
4057     IHTMLElement_Release(elem);
4058     ok_(__FILE__,line) (hres == S_OK, "put_className failed: %08x\n", hres);
4059     SysFreeString(tmp);
4060 
4061     _test_elem_class(line, unk, class);
4062 }
4063 
4064 #define test_elem_title(u,t) _test_elem_title(__LINE__,u,t)
_test_elem_title(unsigned line,IUnknown * unk,const char * extitle)4065 static void _test_elem_title(unsigned line, IUnknown *unk, const char *extitle)
4066 {
4067     IHTMLElement *elem = _get_elem_iface(line, unk);
4068     BSTR title;
4069     HRESULT hres;
4070 
4071     hres = IHTMLElement_get_title(elem, &title);
4072     IHTMLElement_Release(elem);
4073     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
4074     if(extitle)
4075         ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
4076     else
4077         ok_(__FILE__,line) (!title, "title=%s, expected NULL\n", wine_dbgstr_w(title));
4078 
4079     SysFreeString(title);
4080 }
4081 
4082 #define test_elem_set_title(u,t) _test_elem_set_title(__LINE__,u,t)
_test_elem_set_title(unsigned line,IUnknown * unk,const char * title)4083 static void _test_elem_set_title(unsigned line, IUnknown *unk, const char *title)
4084 {
4085     IHTMLElement *elem = _get_elem_iface(line, unk);
4086     BSTR tmp;
4087     HRESULT hres;
4088 
4089     tmp = a2bstr(title);
4090     hres = IHTMLElement_put_title(elem, tmp);
4091     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
4092 
4093     IHTMLElement_Release(elem);
4094     SysFreeString(tmp);
4095 }
4096 
4097 #define test_node_get_value_str(u,e) _test_node_get_value_str(__LINE__,u,e)
_test_node_get_value_str(unsigned line,IUnknown * unk,const char * exval)4098 static void _test_node_get_value_str(unsigned line, IUnknown *unk, const char *exval)
4099 {
4100     IHTMLDOMNode *node = _get_node_iface(line, unk);
4101     VARIANT var;
4102     HRESULT hres;
4103 
4104     hres = IHTMLDOMNode_get_nodeValue(node, &var);
4105     IHTMLDOMNode_Release(node);
4106     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
4107 
4108     if(exval) {
4109         ok_(__FILE__,line) (V_VT(&var) == VT_BSTR, "vt=%d\n", V_VT(&var));
4110         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&var), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&var)));
4111     }else {
4112         ok_(__FILE__,line) (V_VT(&var) == VT_NULL, "vt=%d, expected VT_NULL\n", V_VT(&var));
4113     }
4114 
4115     VariantClear(&var);
4116 }
4117 
4118 #define test_node_put_value_str(u,v) _test_node_put_value_str(__LINE__,u,v)
_test_node_put_value_str(unsigned line,IUnknown * unk,const char * val)4119 static void _test_node_put_value_str(unsigned line, IUnknown *unk, const char *val)
4120 {
4121     IHTMLDOMNode *node = _get_node_iface(line, unk);
4122     VARIANT var;
4123     HRESULT hres;
4124 
4125     V_VT(&var) = VT_BSTR;
4126     V_BSTR(&var) = a2bstr(val);
4127 
4128     hres = IHTMLDOMNode_put_nodeValue(node, var);
4129     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
4130     IHTMLDOMNode_Release(node);
4131     VariantClear(&var);
4132 }
4133 
4134 #define test_elem_client_size(u) _test_elem_client_size(__LINE__,u)
_test_elem_client_size(unsigned line,IUnknown * unk)4135 static void _test_elem_client_size(unsigned line, IUnknown *unk)
4136 {
4137     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
4138     LONG l;
4139     HRESULT hres;
4140 
4141     hres = IHTMLElement2_get_clientWidth(elem, &l);
4142     ok_(__FILE__,line) (hres == S_OK, "get_clientWidth failed: %08x\n", hres);
4143     hres = IHTMLElement2_get_clientHeight(elem, &l);
4144     ok_(__FILE__,line) (hres == S_OK, "get_clientHeight failed: %08x\n", hres);
4145 
4146     IHTMLElement2_Release(elem);
4147 }
4148 
4149 #define test_elem_client_rect(u) _test_elem_client_rect(__LINE__,u)
_test_elem_client_rect(unsigned line,IUnknown * unk)4150 static void _test_elem_client_rect(unsigned line, IUnknown *unk)
4151 {
4152     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
4153     LONG l;
4154     HRESULT hres;
4155 
4156     hres = IHTMLElement2_get_clientLeft(elem, &l);
4157     ok_(__FILE__,line) (hres == S_OK, "get_clientLeft failed: %08x\n", hres);
4158     ok_(__FILE__,line) (!l, "clientLeft = %d\n", l);
4159 
4160     hres = IHTMLElement2_get_clientTop(elem, &l);
4161     ok_(__FILE__,line) (hres == S_OK, "get_clientTop failed: %08x\n", hres);
4162     ok_(__FILE__,line) (!l, "clientTop = %d\n", l);
4163 
4164     IHTMLElement2_Release(elem);
4165 }
4166 
4167 #define test_form_length(e,l) _test_form_length(__LINE__,e,l)
_test_form_length(unsigned line,IUnknown * unk,LONG exlen)4168 static void _test_form_length(unsigned line, IUnknown *unk, LONG exlen)
4169 {
4170     IHTMLFormElement *form = _get_form_iface(line, unk);
4171     LONG len = 0xdeadbeef;
4172     HRESULT hres;
4173 
4174     hres = IHTMLFormElement_get_length(form, &len);
4175     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
4176     ok_(__FILE__,line)(len == exlen, "length=%d, expected %d\n", len, exlen);
4177 
4178     IHTMLFormElement_Release(form);
4179 }
4180 
4181 #define test_form_action(f,a) _test_form_action(__LINE__,f,a)
_test_form_action(unsigned line,IUnknown * unk,const char * ex)4182 static void _test_form_action(unsigned line, IUnknown *unk, const char *ex)
4183 {
4184     IHTMLFormElement *form = _get_form_iface(line, unk);
4185     BSTR action = (void*)0xdeadbeef;
4186     HRESULT hres;
4187 
4188     hres = IHTMLFormElement_get_action(form, &action);
4189     ok_(__FILE__,line)(hres == S_OK, "get_action failed: %08x\n", hres);
4190     if(ex)
4191         ok_(__FILE__,line)(!strcmp_wa(action, ex), "action=%s, expected %s\n", wine_dbgstr_w(action), ex);
4192     else
4193         ok_(__FILE__,line)(!action, "action=%p\n", action);
4194 
4195     SysFreeString(action);
4196     IHTMLFormElement_Release(form);
4197 }
4198 
4199 #define test_form_put_action(f,a) _test_form_put_action(__LINE__,f,a)
_test_form_put_action(unsigned line,IUnknown * unk,const char * action)4200 static void _test_form_put_action(unsigned line, IUnknown *unk, const char *action)
4201 {
4202     IHTMLFormElement *form = _get_form_iface(line, unk);
4203     BSTR tmp = a2bstr(action);
4204     HRESULT hres;
4205 
4206     hres = IHTMLFormElement_put_action(form, tmp);
4207     ok_(__FILE__,line)(hres == S_OK, "put_action failed: %08x\n", hres);
4208     SysFreeString(tmp);
4209     IHTMLFormElement_Release(form);
4210 
4211     _test_form_action(line, unk, action);
4212 }
4213 
4214 #define test_form_method(f,a) _test_form_method(__LINE__,f,a)
_test_form_method(unsigned line,IUnknown * unk,const char * ex)4215 static void _test_form_method(unsigned line, IUnknown *unk, const char *ex)
4216 {
4217     IHTMLFormElement *form = _get_form_iface(line, unk);
4218     BSTR method = (void*)0xdeadbeef;
4219     HRESULT hres;
4220 
4221     hres = IHTMLFormElement_get_method(form, &method);
4222     ok_(__FILE__,line)(hres == S_OK, "get_method failed: %08x\n", hres);
4223     if(ex)
4224         ok_(__FILE__,line)(!strcmp_wa(method, ex), "method=%s, expected %s\n", wine_dbgstr_w(method), ex);
4225     else
4226         ok_(__FILE__,line)(!method, "method=%p\n", method);
4227 
4228     SysFreeString(method);
4229     IHTMLFormElement_Release(form);
4230 }
4231 
4232 #define test_form_put_method(f,r,a) _test_form_put_method(__LINE__,f,r,a)
_test_form_put_method(unsigned line,IUnknown * unk,HRESULT exp_hres,const char * method)4233 static void _test_form_put_method(unsigned line, IUnknown *unk, HRESULT exp_hres, const char *method)
4234 {
4235     IHTMLFormElement *form = _get_form_iface(line, unk);
4236     BSTR tmp = a2bstr(method);
4237     HRESULT hres;
4238 
4239     hres = IHTMLFormElement_put_method(form, tmp);
4240     ok_(__FILE__,line)(hres == exp_hres, "put_method returned: %08x, expected %08x\n", hres, exp_hres);
4241     SysFreeString(tmp);
4242     IHTMLFormElement_Release(form);
4243 
4244     if(exp_hres == S_OK)
4245         _test_form_method(line, unk, method);
4246 }
4247 
4248 #define test_form_name(f,a) _test_form_name(__LINE__,f,a)
_test_form_name(unsigned line,IUnknown * unk,const char * ex)4249 static void _test_form_name(unsigned line, IUnknown *unk, const char *ex)
4250 {
4251     IHTMLFormElement *form = _get_form_iface(line, unk);
4252     BSTR name = (void*)0xdeadbeef;
4253     HRESULT hres;
4254 
4255     hres = IHTMLFormElement_get_name(form, &name);
4256     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
4257     if(ex)
4258         ok_(__FILE__,line)(!strcmp_wa(name, ex), "name=%s, expected %s\n", wine_dbgstr_w(name), ex);
4259     else
4260         ok_(__FILE__,line)(!name, "name=%p\n", name);
4261 
4262     SysFreeString(name);
4263     IHTMLFormElement_Release(form);
4264 }
4265 
4266 #define test_form_put_name(f,a) _test_form_put_name(__LINE__,f,a)
_test_form_put_name(unsigned line,IUnknown * unk,const char * name)4267 static void _test_form_put_name(unsigned line, IUnknown *unk, const char *name)
4268 {
4269     IHTMLFormElement *form = _get_form_iface(line, unk);
4270     BSTR tmp = a2bstr(name);
4271     HRESULT hres;
4272 
4273     hres = IHTMLFormElement_put_name(form, tmp);
4274     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
4275     SysFreeString(tmp);
4276     IHTMLFormElement_Release(form);
4277 
4278     _test_form_name(line, unk, name);
4279 }
4280 
4281 #define test_form_encoding(f,a) _test_form_encoding(__LINE__,f,a)
_test_form_encoding(unsigned line,IUnknown * unk,const char * ex)4282 static void _test_form_encoding(unsigned line, IUnknown *unk, const char *ex)
4283 {
4284     IHTMLFormElement *form = _get_form_iface(line, unk);
4285     BSTR encoding = (void*)0xdeadbeef;
4286     HRESULT hres;
4287 
4288     hres = IHTMLFormElement_get_encoding(form, &encoding);
4289     ok_(__FILE__,line)(hres == S_OK, "get_encoding failed: %08x\n", hres);
4290     if(ex)
4291         ok_(__FILE__,line)(!strcmp_wa(encoding, ex), "encoding=%s, expected %s\n", wine_dbgstr_w(encoding), ex);
4292     else
4293         ok_(__FILE__,line)(!encoding, "encoding=%p\n", encoding);
4294 
4295     SysFreeString(encoding);
4296     IHTMLFormElement_Release(form);
4297 }
4298 
4299 #define test_form_put_encoding(f,r,a) _test_form_put_encoding(__LINE__,f,r,a)
_test_form_put_encoding(unsigned line,IUnknown * unk,HRESULT exp_hres,const char * encoding)4300 static void _test_form_put_encoding(unsigned line, IUnknown *unk, HRESULT exp_hres, const char *encoding)
4301 {
4302     IHTMLFormElement *form = _get_form_iface(line, unk);
4303     BSTR tmp = a2bstr(encoding);
4304     HRESULT hres;
4305 
4306     hres = IHTMLFormElement_put_encoding(form, tmp);
4307     ok_(__FILE__,line)(hres == exp_hres, "put_encoding returned: %08x, expected %08x\n", hres, exp_hres);
4308     SysFreeString(tmp);
4309     IHTMLFormElement_Release(form);
4310 
4311     if(exp_hres == S_OK)
4312         _test_form_encoding(line, unk, encoding);
4313 }
4314 
4315 #define test_form_elements(a) _test_form_elements(__LINE__,a)
_test_form_elements(unsigned line,IUnknown * unk)4316 static void _test_form_elements(unsigned line, IUnknown *unk)
4317 {
4318     IHTMLFormElement *form = _get_form_iface(line, unk);
4319     IDispatch *disp;
4320     HRESULT hres;
4321 
4322     disp = NULL;
4323     hres = IHTMLFormElement_get_elements(form, &disp);
4324     ok_(__FILE__,line)(hres == S_OK, "get_elements failed: %08x\n", hres);
4325     ok_(__FILE__,line)(disp != NULL, "disp = NULL\n");
4326     ok_(__FILE__,line)(iface_cmp((IUnknown*)form, (IUnknown*)disp), "disp != form\n");
4327 
4328     IDispatch_Release(disp);
4329     IHTMLFormElement_Release(form);
4330 }
4331 
4332 #define test_form_reset(a) _test_form_reset(__LINE__,a)
_test_form_reset(unsigned line,IUnknown * unk)4333 static void _test_form_reset(unsigned line, IUnknown *unk)
4334 {
4335     IHTMLFormElement *form = _get_form_iface(line, unk);
4336     HRESULT hres;
4337 
4338     hres = IHTMLFormElement_reset(form);
4339     ok_(__FILE__,line)(hres == S_OK, "reset failed: %08x\n", hres);
4340 
4341     IHTMLFormElement_Release(form);
4342 }
4343 
test_form_target(IUnknown * unk)4344 static void test_form_target(IUnknown *unk)
4345 {
4346     IHTMLFormElement *form = get_form_iface(unk);
4347     HRESULT hres;
4348     BSTR str;
4349     static const char target[] = "_blank";
4350 
4351     str = a2bstr(target);
4352     hres = IHTMLFormElement_put_target(form, str);
4353     ok(hres == S_OK, "put_target(%s) failed: %08x\n", target, hres);
4354     SysFreeString(str);
4355 
4356     hres = IHTMLFormElement_get_target(form, &str);
4357     ok(hres == S_OK, "get_target failed: %08x\n", hres);
4358     ok(!strcmp_wa(str, target), "Expected %s, got %s\n", target, wine_dbgstr_w(str));
4359     SysFreeString(str);
4360 
4361     IHTMLFormElement_Release(form);
4362 }
4363 
test_select_form(IUnknown * uselect,IUnknown * uform)4364 static void test_select_form(IUnknown *uselect, IUnknown  *uform)
4365 {
4366     IHTMLSelectElement *select = get_select_iface(uselect);
4367     IHTMLFormElement *form;
4368     HRESULT hres;
4369 
4370     hres = IHTMLSelectElement_get_form(select, NULL);
4371     ok(hres == E_POINTER, "got %08x\n, expected E_POINTER\n", hres);
4372 
4373     hres = IHTMLSelectElement_get_form(select, &form);
4374     ok(hres == S_OK, "get_form failed: %08x\n", hres);
4375     ok(form != NULL, "form == NULL\n");
4376 
4377     test_form_length((IUnknown*)form, 1);
4378     test_form_elements((IUnknown*)form);
4379     test_form_name((IUnknown*)form, "form_name");
4380 
4381     ok(iface_cmp(uform, (IUnknown*)form), "Expected %p, got %p\n", uform, form);
4382 
4383     IHTMLSelectElement_Release(select);
4384     IHTMLFormElement_Release(form);
4385 }
4386 
test_select_form_notfound(IHTMLSelectElement * select)4387 static void test_select_form_notfound(IHTMLSelectElement *select)
4388 {
4389     IHTMLFormElement *form;
4390     HRESULT hres;
4391 
4392     form = (IHTMLFormElement*)0xdeadbeef;
4393     hres = IHTMLSelectElement_get_form(select, &form);
4394     ok(hres == S_OK, "get_form failed: %08x\n", hres);
4395     ok(form == NULL, "got %p\n", form);
4396 }
4397 
4398 #define test_meta_name(a,b) _test_meta_name(__LINE__,a,b)
_test_meta_name(unsigned line,IUnknown * unk,const char * exname)4399 static void _test_meta_name(unsigned line, IUnknown *unk, const char *exname)
4400 {
4401     IHTMLMetaElement *meta;
4402     BSTR name = NULL;
4403     HRESULT hres;
4404 
4405     meta = _get_metaelem_iface(line, unk);
4406     hres = IHTMLMetaElement_get_name(meta, &name);
4407     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
4408     ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s, expected %s\n", wine_dbgstr_w(name), exname);
4409     SysFreeString(name);
4410     IHTMLMetaElement_Release(meta);
4411 }
4412 
4413 #define test_meta_content(a,b) _test_meta_content(__LINE__,a,b)
_test_meta_content(unsigned line,IUnknown * unk,const char * excontent)4414 static void _test_meta_content(unsigned line, IUnknown *unk, const char *excontent)
4415 {
4416     IHTMLMetaElement *meta;
4417     BSTR content = NULL;
4418     HRESULT hres;
4419 
4420     meta = _get_metaelem_iface(line, unk);
4421     hres = IHTMLMetaElement_get_content(meta, &content);
4422     ok_(__FILE__,line)(hres == S_OK, "get_content failed: %08x\n", hres);
4423     ok_(__FILE__,line)(!strcmp_wa(content, excontent), "content = %s, expected %s\n", wine_dbgstr_w(content), excontent);
4424     SysFreeString(content);
4425     IHTMLMetaElement_Release(meta);
4426 }
4427 
4428 #define test_meta_httpequiv(a,b) _test_meta_httpequiv(__LINE__,a,b)
_test_meta_httpequiv(unsigned line,IUnknown * unk,const char * exval)4429 static void _test_meta_httpequiv(unsigned line, IUnknown *unk, const char *exval)
4430 {
4431     IHTMLMetaElement *meta;
4432     BSTR val = NULL;
4433     HRESULT hres;
4434 
4435     meta = _get_metaelem_iface(line, unk);
4436     hres = IHTMLMetaElement_get_httpEquiv(meta, &val);
4437     ok_(__FILE__,line)(hres == S_OK, "get_httpEquiv failed: %08x\n", hres);
4438     ok_(__FILE__,line)(!strcmp_wa(val, exval), "httpEquiv = %s, expected %s\n", wine_dbgstr_w(val), exval);
4439     SysFreeString(val);
4440     IHTMLMetaElement_Release(meta);
4441 }
4442 
4443 #define test_meta_charset(a,b) _test_meta_charset(__LINE__,a,b)
_test_meta_charset(unsigned line,IUnknown * unk,const char * exval)4444 static void _test_meta_charset(unsigned line, IUnknown *unk, const char *exval)
4445 {
4446     IHTMLMetaElement *meta;
4447     BSTR val = NULL;
4448     HRESULT hres;
4449 
4450     meta = _get_metaelem_iface(line, unk);
4451     hres = IHTMLMetaElement_get_charset(meta, &val);
4452     ok_(__FILE__,line)(hres == S_OK, "get_charset failed: %08x\n", hres);
4453     if(exval)
4454         ok_(__FILE__,line)(!strcmp_wa(val, exval), "charset = %s, expected %s\n", wine_dbgstr_w(val), exval);
4455     else
4456         ok_(__FILE__,line)(!val, "charset = %s, expected NULL\n", wine_dbgstr_w(val));
4457     SysFreeString(val);
4458     IHTMLMetaElement_Release(meta);
4459 }
4460 
4461 #define set_meta_charset(a,b) _set_meta_charset(__LINE__,a,b)
_set_meta_charset(unsigned line,IUnknown * unk,const char * vala)4462 static void _set_meta_charset(unsigned line, IUnknown *unk, const char *vala)
4463 {
4464     BSTR val = a2bstr(vala);
4465     IHTMLMetaElement *meta;
4466     HRESULT hres;
4467 
4468     meta = _get_metaelem_iface(line, unk);
4469     hres = IHTMLMetaElement_put_charset(meta, val);
4470     ok_(__FILE__,line)(hres == S_OK, "put_charset failed: %08x\n", hres);
4471     SysFreeString(val);
4472     IHTMLMetaElement_Release(meta);
4473 
4474     _test_meta_charset(line, unk, vala);
4475 }
4476 
4477 #define test_link_media(a,b) _test_link_media(__LINE__,a,b)
_test_link_media(unsigned line,IHTMLElement * elem,const char * exval)4478 static void _test_link_media(unsigned line, IHTMLElement *elem, const char *exval)
4479 {
4480     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4481     HRESULT hres;
4482     BSTR str;
4483 
4484     str = a2bstr(exval);
4485     hres = IHTMLLinkElement_put_media(link, str);
4486     ok_(__FILE__,line)(hres == S_OK, "put_media(%s) failed: %08x\n", exval, hres);
4487     SysFreeString(str);
4488 
4489     hres = IHTMLLinkElement_get_media(link, &str);
4490     ok_(__FILE__,line)(hres == S_OK, "get_media failed: %08x\n", hres);
4491     ok_(__FILE__,line)(!strcmp_wa(str, exval), "got %s, expected %s\n", wine_dbgstr_w(str), exval);
4492     SysFreeString(str);
4493     IHTMLLinkElement_Release(link);
4494 }
4495 
4496 #define test_link_disabled(a,b) _test_link_disabled(__LINE__,a,b)
_test_link_disabled(unsigned line,IHTMLElement * elem,VARIANT_BOOL v)4497 static void _test_link_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL v)
4498 {
4499     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4500     VARIANT_BOOL b = 10;
4501     HRESULT hres;
4502 
4503     hres = IHTMLLinkElement_get_disabled(link, &b);
4504     ok_(__FILE__,line)(hres == S_OK, "get_disabled failed: %08x\n", hres);
4505     ok_(__FILE__,line)(b == v, "disabled = %x, expected %x\n", b, v);
4506 
4507     IHTMLLinkElement_Release(link);
4508 }
4509 
4510 #define link_put_disabled(a,b) _link_put_disabled(__LINE__,a,b)
_link_put_disabled(unsigned line,IHTMLElement * elem,VARIANT_BOOL v)4511 static void _link_put_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL v)
4512 {
4513     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4514     HRESULT hres;
4515 
4516     hres = IHTMLLinkElement_put_disabled(link, v);
4517     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
4518     IHTMLLinkElement_Release(link);
4519     _test_link_disabled(line, elem, v);
4520 }
4521 
4522 #define test_link_rel(a,b) _test_link_rel(__LINE__,a,b)
_test_link_rel(unsigned line,IHTMLElement * elem,const char * v)4523 static void _test_link_rel(unsigned line, IHTMLElement *elem, const char *v)
4524 {
4525     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4526     BSTR rel;
4527     HRESULT hres;
4528 
4529     hres = IHTMLLinkElement_get_rel(link, &rel);
4530     ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
4531     if(v)
4532         ok_(__FILE__,line)(!strcmp_wa(rel, v), "rel = %s, expected %s\n", wine_dbgstr_w(rel), v);
4533     else
4534         ok_(__FILE__,line)(!rel, "rel = %s, expected NULL\n", wine_dbgstr_w(rel));
4535 
4536     IHTMLLinkElement_Release(link);
4537 }
4538 
4539 #define link_put_rel(a,b) _link_put_rel(__LINE__,a,b)
_link_put_rel(unsigned line,IHTMLElement * elem,const char * v)4540 static void _link_put_rel(unsigned line, IHTMLElement *elem, const char *v)
4541 {
4542     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4543     BSTR str = a2bstr(v);
4544     HRESULT hres;
4545 
4546     hres = IHTMLLinkElement_put_rel(link, str);
4547     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
4548     SysFreeString(str);
4549     IHTMLLinkElement_Release(link);
4550     _test_link_rel(line, elem, v);
4551 }
4552 
4553 #define test_link_rev(a,b) _test_link_rev(__LINE__,a,b)
_test_link_rev(unsigned line,IHTMLElement * elem,const char * v)4554 static void _test_link_rev(unsigned line, IHTMLElement *elem, const char *v)
4555 {
4556     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4557     BSTR rev;
4558     HRESULT hres;
4559 
4560     hres = IHTMLLinkElement_get_rev(link, &rev);
4561     ok_(__FILE__,line)(hres == S_OK, "get_rev failed: %08x\n", hres);
4562     if(v)
4563         ok_(__FILE__,line)(!strcmp_wa(rev, v), "rev = %s, expected %s\n", wine_dbgstr_w(rev), v);
4564     else
4565         ok_(__FILE__,line)(!rev, "rev = %s, expected NULL\n", wine_dbgstr_w(rev));
4566 
4567     IHTMLLinkElement_Release(link);
4568 }
4569 
4570 #define link_put_rev(a,b) _link_put_rev(__LINE__,a,b)
_link_put_rev(unsigned line,IHTMLElement * elem,const char * v)4571 static void _link_put_rev(unsigned line, IHTMLElement *elem, const char *v)
4572 {
4573     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4574     BSTR str = a2bstr(v);
4575     HRESULT hres;
4576 
4577     hres = IHTMLLinkElement_put_rev(link, str);
4578     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
4579     SysFreeString(str);
4580     IHTMLLinkElement_Release(link);
4581     _test_link_rev(line, elem, v);
4582 }
4583 
4584 #define test_link_type(a,b) _test_link_type(__LINE__,a,b)
_test_link_type(unsigned line,IHTMLElement * elem,const char * v)4585 static void _test_link_type(unsigned line, IHTMLElement *elem, const char *v)
4586 {
4587     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4588     BSTR type;
4589     HRESULT hres;
4590 
4591     hres = IHTMLLinkElement_get_type(link, &type);
4592     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
4593     if(v)
4594         ok_(__FILE__,line)(!strcmp_wa(type, v), "type = %s, expected %s\n", wine_dbgstr_w(type), v);
4595     else
4596         ok_(__FILE__,line)(!type, "type = %s, expected NULL\n", wine_dbgstr_w(type));
4597 
4598     IHTMLLinkElement_Release(link);
4599 }
4600 
4601 #define test_script_text(a,b) _test_script_text(__LINE__,a,b)
_test_script_text(unsigned line,IHTMLScriptElement * script,const char * extext)4602 static void _test_script_text(unsigned line, IHTMLScriptElement *script, const char *extext)
4603 {
4604     BSTR str;
4605     HRESULT hres;
4606 
4607     str = (void*)0xdeadbeef;
4608     hres = IHTMLScriptElement_get_text(script, &str);
4609     ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
4610     ok(!strcmp_wa(str, extext), "text = %s, expected \"%s\"\n", wine_dbgstr_w(str), extext);
4611     SysFreeString(str);
4612 }
4613 
4614 #define link_put_type(a,b) _link_put_type(__LINE__,a,b)
_link_put_type(unsigned line,IHTMLElement * elem,const char * v)4615 static void _link_put_type(unsigned line, IHTMLElement *elem, const char *v)
4616 {
4617     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4618     BSTR str = a2bstr(v);
4619     HRESULT hres;
4620 
4621     hres = IHTMLLinkElement_put_type(link, str);
4622     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
4623     SysFreeString(str);
4624     IHTMLLinkElement_Release(link);
4625     _test_link_type(line, elem, v);
4626 }
4627 
4628 #define test_link_href(a,b) _test_link_href(__LINE__,a,b)
_test_link_href(unsigned line,IHTMLElement * elem,const char * v)4629 static void _test_link_href(unsigned line, IHTMLElement *elem, const char *v)
4630 {
4631     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4632     BSTR href;
4633     HRESULT hres;
4634 
4635     hres = IHTMLLinkElement_get_href(link, &href);
4636     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
4637     if(v)
4638         ok_(__FILE__,line)(!strcmp_wa(href, v), "href = %s, expected %s\n", wine_dbgstr_w(href), v);
4639     else
4640         ok_(__FILE__,line)(!href, "href = %s, expected NULL\n", wine_dbgstr_w(href));
4641 
4642     IHTMLLinkElement_Release(link);
4643 }
4644 
4645 #define link_put_href(a,b) _link_put_href(__LINE__,a,b)
_link_put_href(unsigned line,IHTMLElement * elem,const char * v)4646 static void _link_put_href(unsigned line, IHTMLElement *elem, const char *v)
4647 {
4648     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
4649     BSTR str = a2bstr(v);
4650     HRESULT hres;
4651 
4652     hres = IHTMLLinkElement_put_href(link, str);
4653     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
4654     SysFreeString(str);
4655     IHTMLLinkElement_Release(link);
4656     _test_link_href(line, elem, v);
4657 }
4658 
4659 #define get_elem_doc(e) _get_elem_doc(__LINE__,e)
_get_elem_doc(unsigned line,IUnknown * unk)4660 static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk)
4661 {
4662     IHTMLElement *elem = _get_elem_iface(line, unk);
4663     IHTMLDocument2 *doc;
4664     IDispatch *disp;
4665     HRESULT hres;
4666 
4667     disp = NULL;
4668     hres = IHTMLElement_get_document(elem, &disp);
4669     ok(hres == S_OK, "get_document failed: %08x\n", hres);
4670     ok(disp != NULL, "disp == NULL\n");
4671 
4672     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
4673     IDispatch_Release(disp);
4674     ok(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
4675 
4676     return doc;
4677 }
4678 
4679 #define get_elem_attr_node(a,b,c) _get_elem_attr_node(__LINE__,a,b,c)
_get_elem_attr_node(unsigned line,IUnknown * unk,const char * attr_name,BOOL expect_success)4680 static IHTMLDOMAttribute *_get_elem_attr_node(unsigned line, IUnknown *unk, const char *attr_name, BOOL expect_success)
4681 {
4682     IHTMLElement4 *elem = _get_elem4_iface(line, unk);
4683     BSTR str = a2bstr(attr_name);
4684     IHTMLDOMAttribute *attr;
4685     HRESULT hres;
4686 
4687     attr = (void*)0xdeadbeef;
4688     hres = IHTMLElement4_getAttributeNode(elem, str, &attr);
4689     ok_(__FILE__,line)(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
4690     if(expect_success)
4691         ok_(__FILE__,line)(attr != NULL, "attr = NULL\n");
4692     else
4693         ok_(__FILE__,line)(!attr, "attr = %p\n", attr);
4694 
4695     IHTMLElement4_Release(elem);
4696     SysFreeString(str);
4697     return attr;
4698 }
4699 
4700 #define get_attr_node_value(a,b,c) _get_attr_node_value(__LINE__,a,b,c)
_get_attr_node_value(unsigned line,IHTMLDOMAttribute * attr,VARIANT * v,VARTYPE vt)4701 static void _get_attr_node_value(unsigned line, IHTMLDOMAttribute *attr, VARIANT *v, VARTYPE vt)
4702 {
4703     HRESULT hres;
4704 
4705     hres = IHTMLDOMAttribute_get_nodeValue(attr, v);
4706     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x\n", hres);
4707     ok_(__FILE__,line) (V_VT(v) == vt, "vt=%d, expected %d\n", V_VT(v), vt);
4708 }
4709 
4710 #define put_attr_node_value(a,b) _put_attr_node_value(__LINE__,a,b)
_put_attr_node_value(unsigned line,IHTMLDOMAttribute * attr,VARIANT v)4711 static void _put_attr_node_value(unsigned line, IHTMLDOMAttribute *attr, VARIANT v)
4712 {
4713     HRESULT hres;
4714 
4715     hres = IHTMLDOMAttribute_put_nodeValue(attr, v);
4716     ok_(__FILE__,line) (hres == S_OK, "put_nodeValue failed: %08x\n", hres);
4717 }
4718 
4719 #define get_window_doc(e) _get_window_doc(__LINE__,e)
_get_window_doc(unsigned line,IHTMLWindow2 * window)4720 static IHTMLDocument2 *_get_window_doc(unsigned line, IHTMLWindow2 *window)
4721 {
4722     IHTMLDocument2 *doc;
4723     HRESULT hres;
4724 
4725     doc = NULL;
4726     hres = IHTMLWindow2_get_document(window, &doc);
4727     ok(hres == S_OK, "get_document failed: %08x\n", hres);
4728     ok(doc != NULL, "disp == NULL\n");
4729 
4730     return doc;
4731 }
4732 
4733 #define doc_get_body(d) _doc_get_body(__LINE__,d)
_doc_get_body(unsigned line,IHTMLDocument2 * doc)4734 static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc)
4735 {
4736     IHTMLElement *elem;
4737     HRESULT hres;
4738 
4739     hres = IHTMLDocument2_get_body(doc, &elem);
4740     ok_(__FILE__,line)(hres == S_OK, "get_body failed: %08x\n", hres);
4741     ok_(__FILE__,line)(elem != NULL, "body == NULL\n");
4742 
4743     return elem;
4744 }
4745 
4746 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
_test_create_elem(unsigned line,IHTMLDocument2 * doc,const char * tag)4747 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
4748 {
4749     IHTMLElement *elem = NULL;
4750     BSTR tmp;
4751     HRESULT hres;
4752 
4753     tmp = a2bstr(tag);
4754     hres = IHTMLDocument2_createElement(doc, tmp, &elem);
4755     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
4756     ok_(__FILE__,line) (elem != NULL, "elem == NULL\n");
4757     SysFreeString(tmp);
4758 
4759     return elem;
4760 }
4761 
4762 #define test_create_text(d,t) _test_create_text(__LINE__,d,t)
_test_create_text(unsigned line,IHTMLDocument2 * doc,const char * text)4763 static IHTMLDOMNode *_test_create_text(unsigned line, IHTMLDocument2 *doc, const char *text)
4764 {
4765     IHTMLDocument3 *doc3;
4766     IHTMLDOMNode *node = NULL;
4767     BSTR tmp;
4768     HRESULT hres;
4769 
4770     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4771     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3: %08x\n", hres);
4772 
4773     tmp = a2bstr(text);
4774     hres = IHTMLDocument3_createTextNode(doc3, tmp, &node);
4775     IHTMLDocument3_Release(doc3);
4776     SysFreeString(tmp);
4777     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
4778     ok_(__FILE__,line) (node != NULL, "node == NULL\n");
4779 
4780     return node;
4781 }
4782 
4783 #define test_node_append_child(n,c) _test_node_append_child(__LINE__,n,c)
_test_node_append_child(unsigned line,IUnknown * node_unk,IUnknown * child_unk)4784 static IHTMLDOMNode *_test_node_append_child(unsigned line, IUnknown *node_unk, IUnknown *child_unk)
4785 {
4786     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
4787     IHTMLDOMNode *child = _get_node_iface(line, child_unk);
4788     IHTMLDOMNode *new_child = NULL;
4789     HRESULT hres;
4790 
4791     hres = IHTMLDOMNode_appendChild(node, child, &new_child);
4792     ok_(__FILE__,line) (hres == S_OK, "appendChild failed: %08x\n", hres);
4793     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
4794     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
4795 
4796     IHTMLDOMNode_Release(node);
4797     IHTMLDOMNode_Release(child);
4798 
4799     return new_child;
4800 }
4801 
4802 #define test_node_insertbefore(n,c,v) _test_node_insertbefore(__LINE__,n,c,v)
_test_node_insertbefore(unsigned line,IUnknown * node_unk,IHTMLDOMNode * child,VARIANT * var)4803 static IHTMLDOMNode *_test_node_insertbefore(unsigned line, IUnknown *node_unk, IHTMLDOMNode *child, VARIANT *var)
4804 {
4805     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
4806     IHTMLDOMNode *new_child = NULL;
4807     HRESULT hres;
4808 
4809     hres = IHTMLDOMNode_insertBefore(node, child, *var, &new_child);
4810     ok_(__FILE__,line) (hres == S_OK, "insertBefore failed: %08x\n", hres);
4811     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
4812     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
4813 
4814     IHTMLDOMNode_Release(node);
4815 
4816     return new_child;
4817 }
4818 
4819 #define test_node_remove_child(n,c) _test_node_remove_child(__LINE__,n,c)
_test_node_remove_child(unsigned line,IUnknown * unk,IHTMLDOMNode * child)4820 static void _test_node_remove_child(unsigned line, IUnknown *unk, IHTMLDOMNode *child)
4821 {
4822     IHTMLDOMNode *node = _get_node_iface(line, unk);
4823     IHTMLDOMNode *new_node = NULL;
4824     HRESULT hres;
4825 
4826     hres = IHTMLDOMNode_removeChild(node, child, &new_node);
4827     ok_(__FILE__,line) (hres == S_OK, "removeChild failed: %08x\n", hres);
4828     ok_(__FILE__,line) (new_node != NULL, "new_node == NULL\n");
4829     /* TODO ok_(__FILE__,line) (new_node != child, "new_node == child\n"); */
4830 
4831     IHTMLDOMNode_Release(node);
4832     IHTMLDOMNode_Release(new_node);
4833 }
4834 
4835 #define test_doc_title(d,t) _test_doc_title(__LINE__,d,t)
_test_doc_title(unsigned line,IHTMLDocument2 * doc,const char * extitle)4836 static void _test_doc_title(unsigned line, IHTMLDocument2 *doc, const char *extitle)
4837 {
4838     BSTR title = NULL;
4839     HRESULT hres;
4840 
4841     hres = IHTMLDocument2_get_title(doc, &title);
4842     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
4843     ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
4844     SysFreeString(title);
4845 }
4846 
4847 #define test_doc_set_title(d,t) _test_doc_set_title(__LINE__,d,t)
_test_doc_set_title(unsigned line,IHTMLDocument2 * doc,const char * title)4848 static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *title)
4849 {
4850     BSTR tmp;
4851     HRESULT hres;
4852 
4853     tmp = a2bstr(title);
4854     hres = IHTMLDocument2_put_title(doc, tmp);
4855     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
4856     SysFreeString(tmp);
4857 }
4858 
test_elem_bounding_client_rect(IUnknown * unk)4859 static void test_elem_bounding_client_rect(IUnknown *unk)
4860 {
4861     IHTMLRect *rect, *rect2;
4862     IHTMLElement2 *elem2;
4863     LONG l;
4864     HRESULT hres;
4865 
4866     elem2 = get_elem2_iface(unk);
4867     hres = IHTMLElement2_getBoundingClientRect(elem2, &rect);
4868     ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres);
4869     hres = IHTMLElement2_getBoundingClientRect(elem2, &rect2);
4870     IHTMLElement2_Release(elem2);
4871     ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres);
4872     ok(rect != NULL, "rect == NULL\n");
4873     ok(rect != rect2, "rect == rect2\n");
4874     IHTMLRect_Release(rect2);
4875 
4876     test_disp((IUnknown*)rect, &IID_IHTMLRect, "[object]");
4877 
4878     l = 0xdeadbeef;
4879     hres = IHTMLRect_get_top(rect, &l);
4880     ok(hres == S_OK, "get_top failed: %08x\n", hres);
4881     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
4882 
4883     l = 0xdeadbeef;
4884     hres = IHTMLRect_get_left(rect, &l);
4885     ok(hres == S_OK, "get_left failed: %08x\n", hres);
4886     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
4887 
4888     l = 0xdeadbeef;
4889     hres = IHTMLRect_get_bottom(rect, &l);
4890     ok(hres == S_OK, "get_bottom failed: %08x\n", hres);
4891     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
4892 
4893     l = 0xdeadbeef;
4894     hres = IHTMLRect_get_right(rect, &l);
4895     ok(hres == S_OK, "get_right failed: %08x\n", hres);
4896     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
4897 
4898     IHTMLRect_Release(rect);
4899 }
4900 
test_elem_col_item(IHTMLElementCollection * col,const char * n,const elem_type_t * elem_types,LONG len)4901 static void test_elem_col_item(IHTMLElementCollection *col, const char *n,
4902         const elem_type_t *elem_types, LONG len)
4903 {
4904     IDispatch *disp;
4905     VARIANT name, index;
4906     DWORD i;
4907     HRESULT hres;
4908 
4909     V_VT(&index) = VT_EMPTY;
4910     V_VT(&name) = VT_BSTR;
4911     V_BSTR(&name) = a2bstr(n);
4912 
4913     hres = IHTMLElementCollection_item(col, name, index, &disp);
4914     ok(hres == S_OK, "item failed: %08x\n", hres);
4915 
4916     test_elem_collection((IUnknown*)disp, elem_types, len);
4917     IDispatch_Release(disp);
4918 
4919     V_VT(&index) = VT_I4;
4920 
4921     for(i=0; i<len; i++) {
4922         V_I4(&index) = i;
4923         disp = (void*)0xdeadbeef;
4924         hres = IHTMLElementCollection_item(col, name, index, &disp);
4925         ok(hres == S_OK, "item failed: %08x\n", hres);
4926         ok(disp != NULL, "disp == NULL\n");
4927         if(FAILED(hres) || !disp)
4928             continue;
4929 
4930         test_elem_type((IUnknown*)disp, elem_types[i]);
4931 
4932         IDispatch_Release(disp);
4933     }
4934 
4935     V_I4(&index) = len;
4936     disp = (void*)0xdeadbeef;
4937     hres = IHTMLElementCollection_item(col, name, index, &disp);
4938     ok(hres == S_OK, "item failed: %08x\n", hres);
4939     ok(disp == NULL, "disp != NULL\n");
4940 
4941     V_I4(&index) = -1;
4942     disp = (void*)0xdeadbeef;
4943     hres = IHTMLElementCollection_item(col, name, index, &disp);
4944     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4945     ok(disp == NULL, "disp != NULL\n");
4946 
4947     SysFreeString(V_BSTR(&name));
4948 }
4949 
get_elem_by_id(IHTMLDocument2 * doc,const char * id,BOOL expect_success)4950 static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const char *id, BOOL expect_success)
4951 {
4952     IHTMLElementCollection *col;
4953     IHTMLElement *elem;
4954     IDispatch *disp = (void*)0xdeadbeef;
4955     VARIANT name, index;
4956     HRESULT hres;
4957 
4958     hres = IHTMLDocument2_get_all(doc, &col);
4959     ok(hres == S_OK, "get_all failed: %08x\n", hres);
4960     ok(col != NULL, "col == NULL\n");
4961     if(FAILED(hres) || !col)
4962         return NULL;
4963 
4964     V_VT(&index) = VT_EMPTY;
4965     V_VT(&name) = VT_BSTR;
4966     V_BSTR(&name) = a2bstr(id);
4967 
4968     hres = IHTMLElementCollection_item(col, name, index, &disp);
4969     IHTMLElementCollection_Release(col);
4970     SysFreeString(V_BSTR(&name));
4971     ok(hres == S_OK, "item failed: %08x\n", hres);
4972     if(!expect_success) {
4973         ok(disp == NULL, "disp != NULL\n");
4974         return NULL;
4975     }
4976 
4977     ok(disp != NULL, "disp == NULL\n");
4978     if(!disp)
4979         return NULL;
4980 
4981     elem = get_elem_iface((IUnknown*)disp);
4982     IDispatch_Release(disp);
4983 
4984     return elem;
4985 }
4986 
get_doc_elem_by_id(IHTMLDocument2 * doc,const char * id)4987 static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const char *id)
4988 {
4989     IHTMLDocument3 *doc3;
4990     IHTMLElement *elem;
4991     BSTR tmp;
4992     HRESULT hres;
4993 
4994     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4995     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
4996 
4997     tmp = a2bstr(id);
4998     hres = IHTMLDocument3_getElementById(doc3, tmp, &elem);
4999     SysFreeString(tmp);
5000     ok(hres == S_OK, "getElementById(%s) failed: %08x\n", id, hres);
5001 
5002     IHTMLDocument3_Release(doc3);
5003 
5004     return elem;
5005 }
5006 
test_select_elem(IHTMLSelectElement * select)5007 static void test_select_elem(IHTMLSelectElement *select)
5008 {
5009     IDispatch *disp, *disp2;
5010     VARIANT name, index;
5011     HRESULT hres;
5012 
5013     test_select_type(select, "select-one");
5014     test_select_length(select, 2);
5015     test_select_selidx(select, 0);
5016     test_select_put_selidx(select, 1);
5017 
5018     test_select_set_value(select, "val1");
5019     test_select_value(select, "val1");
5020 
5021     test_select_size(select, 0);
5022     test_select_set_size(select, 1, S_OK);
5023     test_select_size(select, 1);
5024 
5025     test_select_set_size(select, -1, CTL_E_INVALIDPROPERTYVALUE);
5026     test_select_size(select, 1);
5027     test_select_set_size(select, 3, S_OK);
5028     test_select_size(select, 3);
5029 
5030     test_select_name(select, NULL);
5031     test_select_set_name(select, "select-name");
5032     test_select_name(select, "select-name");
5033     test_select_form_notfound(select);
5034 
5035     test_select_get_disabled(select, VARIANT_FALSE);
5036     test_select_set_disabled(select, VARIANT_TRUE);
5037     test_select_set_disabled(select, VARIANT_FALSE);
5038 
5039     disp = NULL;
5040     hres = IHTMLSelectElement_get_options(select, &disp);
5041     ok(hres == S_OK, "get_options failed: %08x\n", hres);
5042     ok(disp != NULL, "options == NULL\n");
5043     ok(iface_cmp((IUnknown*)disp, (IUnknown*)select), "disp != select\n");
5044     IDispatch_Release(disp);
5045 
5046     V_VT(&index) = VT_EMPTY;
5047     V_VT(&name) = VT_I4;
5048     V_I4(&name) = -1;
5049     disp = (void*)0xdeadbeef;
5050     hres = IHTMLSelectElement_item(select, name, index, &disp);
5051     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5052     ok(!disp, "disp = %p\n", disp);
5053 
5054     V_I4(&name) = 2;
5055     disp = (void*)0xdeadbeef;
5056     hres = IHTMLSelectElement_item(select, name, index, &disp);
5057     ok(hres == S_OK, "item failed: %08x\n", hres);
5058     ok(!disp, "disp = %p\n", disp);
5059 
5060     V_I4(&name) = 1;
5061     hres = IHTMLSelectElement_item(select, name, index, NULL);
5062     ok(hres == E_POINTER || broken(hres == E_INVALIDARG), "item failed: %08x, expected E_POINTER\n", hres);
5063 
5064     disp = NULL;
5065     hres = IHTMLSelectElement_item(select, name, index, &disp);
5066     ok(hres == S_OK, "item failed: %08x\n", hres);
5067     ok(disp != NULL, "disp = NULL\n");
5068     test_disp((IUnknown*)disp, &DIID_DispHTMLOptionElement, NULL);
5069 
5070     V_VT(&index) = VT_I4;
5071     V_I4(&index) = 1;
5072     disp2 = NULL;
5073     hres = IHTMLSelectElement_item(select, name, index, &disp2);
5074     ok(hres == S_OK, "item failed: %08x\n", hres);
5075     ok(disp2 != NULL, "disp = NULL\n");
5076     ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
5077     IDispatch_Release(disp2);
5078     IDispatch_Release(disp);
5079 
5080     test_select_multiple(select, VARIANT_FALSE);
5081     test_select_set_multiple(select, VARIANT_TRUE);
5082     test_select_remove(select);
5083 }
5084 
test_form_item(IHTMLElement * elem)5085 static void test_form_item(IHTMLElement *elem)
5086 {
5087     IHTMLFormElement *form = get_form_iface((IUnknown*)elem);
5088     IDispatch *disp, *disp2;
5089     VARIANT name, index;
5090     HRESULT hres;
5091 
5092     V_VT(&index) = VT_EMPTY;
5093     V_VT(&name) = VT_I4;
5094     V_I4(&name) = -1;
5095     disp = (void*)0xdeadbeef;
5096     hres = IHTMLFormElement_item(form, name, index, &disp);
5097     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5098     ok(!disp, "disp = %p\n", disp);
5099 
5100     V_I4(&name) = 2;
5101     disp = (void*)0xdeadbeef;
5102     hres = IHTMLFormElement_item(form, name, index, &disp);
5103     ok(hres == S_OK, "item failed: %08x\n", hres);
5104     ok(!disp, "disp = %p\n", disp);
5105 
5106     V_I4(&name) = 1;
5107     hres = IHTMLFormElement_item(form, name, index, NULL);
5108     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5109 
5110     disp = NULL;
5111     hres = IHTMLFormElement_item(form, name, index, &disp);
5112     ok(hres == S_OK, "item failed: %08x\n", hres);
5113     ok(disp != NULL, "disp = NULL\n");
5114     test_disp((IUnknown*)disp, &DIID_DispHTMLInputElement, NULL);
5115 
5116     V_VT(&index) = VT_I4;
5117     V_I4(&index) = 1;
5118     disp2 = NULL;
5119     hres = IHTMLFormElement_item(form, name, index, &disp2);
5120     ok(hres == S_OK, "item failed: %08x\n", hres);
5121     ok(disp2 != NULL, "disp = NULL\n");
5122     ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
5123     IDispatch_Release(disp2);
5124     IDispatch_Release(disp);
5125 }
5126 
test_create_option_elem(IHTMLDocument2 * doc)5127 static void test_create_option_elem(IHTMLDocument2 *doc)
5128 {
5129     IHTMLOptionElement *option;
5130 
5131     option = create_option_elem(doc, "test text", "test value");
5132 
5133     test_option_put_text(option, "new text");
5134     test_option_put_value(option, "new value");
5135     test_option_get_index(option, 0);
5136     test_option_defaultSelected_property(option);
5137     test_option_put_selected(option, VARIANT_TRUE);
5138     test_option_put_selected(option, VARIANT_FALSE);
5139 
5140     IHTMLOptionElement_Release(option);
5141 }
5142 
test_option_form(IUnknown * uoption,IUnknown * uform)5143 static void test_option_form(IUnknown *uoption, IUnknown  *uform)
5144 {
5145     IHTMLOptionElement *option = get_option_iface(uoption);
5146     IHTMLFormElement *form;
5147     HRESULT hres;
5148 
5149     hres = IHTMLOptionElement_get_form(option, NULL);
5150     ok(hres == E_POINTER, "got %08x\n, expected E_POINTER\n", hres);
5151 
5152     hres = IHTMLOptionElement_get_form(option, &form);
5153     ok(hres == S_OK, "get_form failed: %08x\n", hres);
5154     ok(form != NULL, "form == NULL\n");
5155 
5156     ok(iface_cmp(uform, (IUnknown*)form), "Expected %p, got %p\n", uform, form);
5157 
5158     IHTMLOptionElement_Release(option);
5159     IHTMLFormElement_Release(form);
5160 }
5161 
test_create_img_elem(IHTMLDocument2 * doc)5162 static void test_create_img_elem(IHTMLDocument2 *doc)
5163 {
5164     IHTMLImgElement *img;
5165 
5166     img = create_img_elem(doc, 10, 15);
5167 
5168     if(img){
5169         test_img_put_width(img, 5);
5170         test_img_put_height(img, 20);
5171 
5172         IHTMLImgElement_Release(img);
5173         img = NULL;
5174     }
5175 
5176     img = create_img_elem(doc, -1, -1);
5177 
5178     if(img){
5179         test_img_put_width(img, 5);
5180         test_img_put_height(img, 20);
5181 
5182         IHTMLImgElement_Release(img);
5183     }
5184 }
5185 
5186 #define insert_adjacent_elem(a,b,c) _insert_adjacent_elem(__LINE__,a,b,c)
_insert_adjacent_elem(unsigned line,IHTMLElement * parent,const char * where,IHTMLElement * elem)5187 static void _insert_adjacent_elem(unsigned line, IHTMLElement *parent, const char *where, IHTMLElement *elem)
5188 {
5189     IHTMLElement2 *elem2 = _get_elem2_iface(line, (IUnknown*)parent);
5190     IHTMLElement *ret_elem = NULL;
5191     BSTR str = a2bstr(where);
5192     HRESULT hres;
5193 
5194     hres = IHTMLElement2_insertAdjacentElement(elem2, str, elem, &ret_elem);
5195     IHTMLElement2_Release(elem2);
5196     SysFreeString(str);
5197     ok_(__FILE__,line)(hres == S_OK, "insertAdjacentElement failed: %08x\n", hres);
5198     ok_(__FILE__,line)(ret_elem == elem, "ret_elem != elem\n");
5199     IHTMLElement_Release(ret_elem);
5200 }
5201 
test_insert_adjacent_elems(IHTMLDocument2 * doc,IHTMLElement * parent)5202 static void test_insert_adjacent_elems(IHTMLDocument2 *doc, IHTMLElement *parent)
5203 {
5204     IHTMLElement *elem, *elem2;
5205 
5206     static const elem_type_t br_br[] = {ET_BR, ET_BR};
5207     static const elem_type_t br_div_br[] = {ET_BR, ET_DIV, ET_BR};
5208 
5209     elem = test_create_elem(doc, "BR");
5210     insert_adjacent_elem(parent, "BeforeEnd", elem);
5211     IHTMLElement_Release(elem);
5212 
5213     test_elem_all((IUnknown*)parent, br_br, 1);
5214 
5215     elem = test_create_elem(doc, "BR");
5216     insert_adjacent_elem(parent, "beforeend", elem);
5217 
5218     test_elem_all((IUnknown*)parent, br_br, 2);
5219 
5220     elem2 = test_create_elem(doc, "DIV");
5221     insert_adjacent_elem(elem, "beforebegin", elem2);
5222     IHTMLElement_Release(elem2);
5223     IHTMLElement_Release(elem);
5224 
5225     test_elem_all((IUnknown*)parent, br_div_br, 3);
5226 }
5227 
test_create_body_range(IHTMLDocument2 * doc)5228 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
5229 {
5230     IHTMLBodyElement *body;
5231     IHTMLTxtRange *range;
5232     IHTMLElement *elem;
5233     HRESULT hres;
5234 
5235     elem = doc_get_body(doc);
5236     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
5237     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
5238     IHTMLElement_Release(elem);
5239 
5240     hres = IHTMLBodyElement_createTextRange(body, &range);
5241     IHTMLBodyElement_Release(body);
5242     ok(hres == S_OK, "createTextRange failed: %08x\n", hres);
5243 
5244     return range;
5245 }
5246 
5247 #define range_duplicate(a) _range_duplicate(__LINE__,a)
_range_duplicate(unsigned line,IHTMLTxtRange * range)5248 static IHTMLTxtRange *_range_duplicate(unsigned line, IHTMLTxtRange *range)
5249 {
5250     IHTMLTxtRange *ret;
5251     HRESULT hres;
5252 
5253     hres = IHTMLTxtRange_duplicate(range, &ret);
5254     ok_(__FILE__,line)(hres == S_OK, "duplicate failed: %08x\n", hres);
5255 
5256     return ret;
5257 }
5258 
5259 #define test_range_set_end_point(a,b,c,d) _test_range_set_end_point(__LINE__,a,b,c,d)
_test_range_set_end_point(unsigned line,IHTMLTxtRange * range,const char * how,IHTMLTxtRange * ref_range,HRESULT exhres)5260 static void _test_range_set_end_point(unsigned line, IHTMLTxtRange *range, const char *how,
5261         IHTMLTxtRange *ref_range, HRESULT exhres)
5262 {
5263     BSTR str = a2bstr(how);
5264     HRESULT hres;
5265 
5266     hres = IHTMLTxtRange_setEndPoint(range, str, ref_range);
5267     ok_(__FILE__,line)(hres == exhres, "setEndPoint failed: %08x, expected %08x\n", hres, exhres);
5268     SysFreeString(str);
5269 }
5270 
test_txtrange(IHTMLDocument2 * doc)5271 static void test_txtrange(IHTMLDocument2 *doc)
5272 {
5273     IHTMLTxtRange *body_range, *range, *range2;
5274     IHTMLSelectionObject *selection;
5275     IDispatch *disp_range;
5276     IHTMLElement *body;
5277     HRESULT hres;
5278 
5279     body_range = test_create_body_range(doc);
5280 
5281     test_disp((IUnknown*)body_range, &IID_IHTMLTxtRange, "[object]");
5282 
5283     test_range_text(body_range, "test abc 123\r\nit's text");
5284 
5285     range = range_duplicate(body_range);
5286     range2 = range_duplicate(body_range);
5287 
5288     test_range_isequal(range, range2, VARIANT_TRUE);
5289 
5290     test_range_text(range, "test abc 123\r\nit's text");
5291     test_range_text(body_range, "test abc 123\r\nit's text");
5292 
5293     test_range_collapse(range, TRUE);
5294     test_range_isequal(range, range2, VARIANT_FALSE);
5295     test_range_inrange(range, range2, VARIANT_FALSE);
5296     test_range_inrange(range2, range, VARIANT_TRUE);
5297     IHTMLTxtRange_Release(range2);
5298 
5299     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
5300     test_range_expand(range, wordW, VARIANT_FALSE, "test ");
5301     test_range_move(range, characterW, 2, 2);
5302     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
5303 
5304     test_range_collapse(range, FALSE);
5305     test_range_expand(range, wordW, VARIANT_TRUE, "abc ");
5306 
5307     test_range_collapse(range, FALSE);
5308     test_range_expand(range, wordW, VARIANT_TRUE, "123");
5309     test_range_expand(range, wordW, VARIANT_FALSE, "123");
5310     test_range_move(range, characterW, 2, 2);
5311     test_range_expand(range, wordW, VARIANT_TRUE, "123");
5312     test_range_moveend(range, characterW, -5, -5);
5313     test_range_text(range, NULL);
5314     test_range_moveend(range, characterW, 3, 3);
5315     test_range_text(range, "c 1");
5316     test_range_expand(range, texteditW, VARIANT_TRUE, "test abc 123\r\nit's text");
5317     test_range_collapse(range, TRUE);
5318     test_range_move(range, characterW, 4, 4);
5319     test_range_moveend(range, characterW, 1, 1);
5320     test_range_text(range, " ");
5321     test_range_move(range, wordW, 1, 1);
5322     test_range_moveend(range, characterW, 2, 2);
5323     test_range_text(range, "ab");
5324 
5325     IHTMLTxtRange_Release(range);
5326 
5327     range = range_duplicate(body_range);
5328 
5329     test_range_text(range, "test abc 123\r\nit's text");
5330     test_range_move(range, characterW, 3, 3);
5331     test_range_moveend(range, characterW, 1, 1);
5332     test_range_text(range, "t");
5333     test_range_moveend(range, characterW, 3, 3);
5334     test_range_text(range, "t ab");
5335     test_range_moveend(range, characterW, -2, -2);
5336     test_range_text(range, "t ");
5337     test_range_move(range, characterW, 6, 6);
5338     test_range_moveend(range, characterW, 3, 3);
5339     test_range_text(range, "123");
5340     test_range_moveend(range, characterW, 2, 2);
5341     test_range_text(range, "123\r\ni");
5342 
5343     IHTMLTxtRange_Release(range);
5344 
5345     range = range_duplicate(body_range);
5346 
5347     test_range_move(range, wordW, 1, 1);
5348     test_range_moveend(range, characterW, 2, 2);
5349     test_range_text(range, "ab");
5350 
5351     test_range_move(range, characterW, -2, -2);
5352     test_range_moveend(range, characterW, 2, 2);
5353     test_range_text(range, "t ");
5354 
5355     test_range_move(range, wordW, 3, 3);
5356     test_range_move(range, wordW, -2, -2);
5357     test_range_moveend(range, characterW, 2, 2);
5358     test_range_text(range, "ab");
5359 
5360     test_range_move(range, characterW, -6, -5);
5361     test_range_moveend(range, characterW, -1, 0);
5362     test_range_moveend(range, characterW, -6, 0);
5363     test_range_move(range, characterW, 2, 2);
5364     test_range_moveend(range, characterW, 2, 2);
5365     test_range_text(range, "st");
5366     test_range_moveend(range, characterW, -6, -4);
5367     test_range_moveend(range, characterW, 2, 2);
5368 
5369     IHTMLTxtRange_Release(range);
5370 
5371     range = range_duplicate(body_range);
5372 
5373     test_range_move(range, wordW, 2, 2);
5374     test_range_moveend(range, characterW, 2, 2);
5375     test_range_text(range, "12");
5376 
5377     test_range_move(range, characterW, 15, 14);
5378     test_range_move(range, characterW, -2, -2);
5379     test_range_moveend(range, characterW, 3, 2);
5380     test_range_text(range, "t");
5381     test_range_moveend(range, characterW, -1, -1);
5382     test_range_text(range, "t");
5383     test_range_expand(range, wordW, VARIANT_TRUE, "text");
5384     test_range_move(range, characterW, -2, -2);
5385     test_range_moveend(range, characterW, 2, 2);
5386     test_range_text(range, "s ");
5387     test_range_move(range, characterW, 100, 7);
5388     test_range_move(range, wordW, 1, 0);
5389     test_range_move(range, characterW, -2, -2);
5390     test_range_moveend(range, characterW, 3, 2);
5391     test_range_text(range, "t");
5392 
5393     IHTMLTxtRange_Release(range);
5394 
5395     range = range_duplicate(body_range);
5396 
5397     test_range_collapse(range, TRUE);
5398     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
5399     test_range_put_text(range, "word");
5400     test_range_text(body_range, "wordabc 123\r\nit's text");
5401     test_range_text(range, NULL);
5402     test_range_moveend(range, characterW, 3, 3);
5403     test_range_text(range, "abc");
5404     test_range_movestart(range, characterW, -2, -2);
5405     test_range_text(range, "rdabc");
5406     test_range_movestart(range, characterW, 3, 3);
5407     test_range_text(range, "bc");
5408     test_range_movestart(range, characterW, 4, 4);
5409     test_range_text(range, NULL);
5410     test_range_movestart(range, characterW, -3, -3);
5411     test_range_text(range, "c 1");
5412     test_range_movestart(range, characterW, -7, -6);
5413     test_range_text(range, "wordabc 1");
5414     test_range_movestart(range, characterW, 100, 22);
5415     test_range_text(range, NULL);
5416 
5417     IHTMLTxtRange_Release(range);
5418 
5419     hres = IHTMLDocument2_get_selection(doc, &selection);
5420     ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres);
5421 
5422     test_disp((IUnknown*)selection, &IID_IHTMLSelectionObject, "[object]");
5423     test_ifaces((IUnknown*)selection, selection_iids);
5424 
5425     hres = IHTMLSelectionObject_createRange(selection, &disp_range);
5426     ok(hres == S_OK, "IHTMLSelectionObject_createRange failed: %08x\n", hres);
5427     IHTMLSelectionObject_Release(selection);
5428 
5429     hres = IDispatch_QueryInterface(disp_range, &IID_IHTMLTxtRange, (void **)&range);
5430     ok(hres == S_OK, "Could not get IID_IHTMLTxtRange interface: 0x%08x\n", hres);
5431     IDispatch_Release(disp_range);
5432 
5433     test_range_text(range, NULL);
5434     test_range_moveend(range, characterW, 3, 3);
5435     test_range_text(range, "wor");
5436     test_range_parent(range, ET_BODY);
5437     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
5438     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
5439     test_range_move(range, characterW, 3, 3);
5440     test_range_expand(range, wordW, VARIANT_TRUE, "wordabc ");
5441     test_range_moveend(range, characterW, -4, -4);
5442     test_range_put_text(range, "abc def ");
5443     test_range_expand(range, texteditW, VARIANT_TRUE, "abc def abc 123\r\nit's text");
5444     test_range_move(range, wordW, 1, 1);
5445     test_range_movestart(range, characterW, -1, -1);
5446     test_range_text(range, " ");
5447     test_range_move(range, wordW, 1, 1);
5448     test_range_moveend(range, characterW, 3, 3);
5449     test_range_text(range, "def");
5450     test_range_put_text(range, "xyz");
5451     test_range_moveend(range, characterW, 1, 1);
5452     test_range_move(range, wordW, 1, 1);
5453     test_range_moveend(range, characterW, 2, 2);
5454     test_range_text(range, "ab");
5455 
5456     body = doc_get_body(doc);
5457 
5458     hres = IHTMLTxtRange_moveToElementText(range, body);
5459     ok(hres == S_OK, "moveToElementText failed: %08x\n", hres);
5460 
5461     test_range_text(range, "abc xyz abc 123\r\nit's text");
5462     test_range_parent(range, ET_BODY);
5463 
5464     test_range_move(range, wordW, 1, 1);
5465     test_range_moveend(range, characterW, 12, 12);
5466     test_range_text(range, "xyz abc 123");
5467 
5468     test_range_collapse(range, VARIANT_TRUE);
5469     test_range_paste_html(range, "<br>paste<br>");
5470     test_range_text(range, NULL);
5471 
5472     test_range_moveend(range, characterW, 3, 3);
5473     test_range_text(range, "xyz");
5474 
5475     hres = IHTMLTxtRange_moveToElementText(range, body);
5476     ok(hres == S_OK, "moveToElementText failed: %08x\n", hres);
5477 
5478     test_range_text(range, "abc \r\npaste\r\nxyz abc 123\r\nit's text");
5479 
5480     test_range_move(range, wordW, 2, 2);
5481     test_range_collapse(range, VARIANT_TRUE);
5482     test_range_moveend(range, characterW, 5, 5);
5483     test_range_text(range, "paste");
5484 
5485     range2 = range_duplicate(range);
5486 
5487     test_range_set_end_point(range, "starttostart", body_range, S_OK);
5488     test_range_text(range, "abc \r\npaste");
5489 
5490     test_range_set_end_point(range, "endtoend", body_range, S_OK);
5491     test_range_text(range, "abc \r\npaste\r\nxyz abc 123\r\nit's text");
5492 
5493     test_range_set_end_point(range, "starttoend", range2, S_OK);
5494     test_range_text(range, "\r\nxyz abc 123\r\nit's text");
5495 
5496     test_range_set_end_point(range, "starttostart", body_range, S_OK);
5497     test_range_set_end_point(range, "endtostart", range2, S_OK);
5498     test_range_text(range, "abc ");
5499 
5500     test_range_set_end_point(range, "starttoend", body_range, S_OK);
5501     test_range_text(range, "paste\r\nxyz abc 123\r\nit's text");
5502 
5503     test_range_set_end_point(range, "EndToStart", body_range, S_OK);
5504     test_range_text(range, "abc ");
5505 
5506     test_range_set_end_point(range, "xxx", body_range, E_INVALIDARG);
5507 
5508     IHTMLTxtRange_Release(range);
5509     IHTMLTxtRange_Release(range2);
5510     IHTMLTxtRange_Release(body_range);
5511     IHTMLElement_Release(body);
5512 
5513 }
5514 
test_txtrange2(IHTMLDocument2 * doc)5515 static void test_txtrange2(IHTMLDocument2 *doc)
5516 {
5517     IHTMLTxtRange *range;
5518 
5519     range = test_create_body_range(doc);
5520 
5521     test_range_text(range, "abc\r\n\r\n123\r\n\r\n\r\ndef");
5522     test_range_move(range, characterW, 5, 5);
5523     test_range_moveend(range, characterW, 1, 1);
5524     test_range_text(range, "2");
5525     test_range_move(range, characterW, -3, -3);
5526     test_range_moveend(range, characterW, 3, 3);
5527     test_range_text(range, "c\r\n\r\n1");
5528     test_range_collapse(range, VARIANT_FALSE);
5529     test_range_moveend(range, characterW, 4, 4);
5530     test_range_text(range, "23");
5531     test_range_moveend(range, characterW, 1, 1);
5532     test_range_text(range, "23\r\n\r\n\r\nd");
5533     test_range_moveend(range, characterW, -1, -1);
5534     test_range_text(range, "23");
5535     test_range_moveend(range, characterW, -1, -1);
5536     test_range_text(range, "23");
5537     test_range_moveend(range, characterW, -2, -2);
5538     test_range_text(range, "2");
5539 
5540     IHTMLTxtRange_Release(range);
5541 }
5542 
5543 #define test_compatmode(a,b) _test_compatmode(__LINE__,a,b)
_test_compatmode(unsigned line,IHTMLDocument2 * doc2,const char * excompat)5544 static void _test_compatmode(unsigned  line, IHTMLDocument2 *doc2, const char *excompat)
5545 {
5546     IHTMLDocument5 *doc = get_htmldoc5_iface((IUnknown*)doc2);
5547     BSTR str;
5548     HRESULT hres;
5549 
5550     hres = IHTMLDocument5_get_compatMode(doc, &str);
5551     ok_(__FILE__,line)(hres == S_OK, "get_compatMode failed: %08x\n", hres);
5552     ok_(__FILE__,line)(!strcmp_wa(str, excompat), "compatMode = %s, expected %s\n", wine_dbgstr_w(str), excompat);
5553 
5554     IHTMLDocument5_Release(doc);
5555 }
5556 
test_location(IHTMLDocument2 * doc)5557 static void test_location(IHTMLDocument2 *doc)
5558 {
5559     IHTMLLocation *location, *location2;
5560     IHTMLWindow2 *window;
5561     BSTR str;
5562     ULONG ref;
5563     HRESULT hres;
5564 
5565     hres = IHTMLDocument2_get_location(doc, &location);
5566     ok(hres == S_OK, "get_location failed: %08x\n", hres);
5567 
5568     hres = IHTMLDocument2_get_location(doc, &location2);
5569     ok(hres == S_OK, "get_location failed: %08x\n", hres);
5570 
5571     ok(location == location2, "location != location2\n");
5572     IHTMLLocation_Release(location2);
5573 
5574     hres = IHTMLDocument2_get_parentWindow(doc, &window);
5575     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
5576 
5577     hres = IHTMLWindow2_get_location(window, &location2);
5578     ok(hres == S_OK, "get_location failed: %08x\n", hres);
5579     ok(location == location2, "location != location2\n");
5580     IHTMLLocation_Release(location2);
5581 
5582     test_ifaces((IUnknown*)location, location_iids);
5583     test_disp2((IUnknown*)location, &DIID_DispHTMLLocation, &IID_IHTMLLocation, "about:blank");
5584 
5585     hres = IHTMLLocation_get_pathname(location, &str);
5586     ok(hres == S_OK, "get_pathname failed: %08x\n", hres);
5587     ok(!strcmp_wa(str, "blank"), "unexpected pathname %s\n", wine_dbgstr_w(str));
5588     SysFreeString(str);
5589 
5590     hres = IHTMLLocation_get_href(location, NULL);
5591     ok(hres == E_POINTER, "get_href passed: %08x\n", hres);
5592 
5593     hres = IHTMLLocation_get_href(location, &str);
5594     ok(hres == S_OK, "get_href failed: %08x\n", hres);
5595     ok(!strcmp_wa(str, "about:blank"), "unexpected href %s\n", wine_dbgstr_w(str));
5596     SysFreeString(str);
5597 
5598     ref = IHTMLLocation_Release(location);
5599     ok(!ref, "location chould be destroyed here\n");
5600 }
5601 
test_plugins_col(IHTMLDocument2 * doc)5602 static void test_plugins_col(IHTMLDocument2 *doc)
5603 {
5604     IHTMLPluginsCollection *col, *col2;
5605     IHTMLWindow2 *window;
5606     IOmNavigator *nav;
5607     ULONG ref;
5608     LONG len;
5609     HRESULT hres;
5610 
5611     window = get_doc_window(doc);
5612     hres = IHTMLWindow2_get_navigator(window, &nav);
5613     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
5614     IHTMLWindow2_Release(window);
5615 
5616     hres = IOmNavigator_get_plugins(nav, &col);
5617     ok(hres == S_OK, "get_plugins failed: %08x\n", hres);
5618 
5619     hres = IOmNavigator_get_plugins(nav, &col2);
5620     ok(hres == S_OK, "get_plugins failed: %08x\n", hres);
5621     ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n");
5622     IHTMLPluginsCollection_Release(col2);
5623 
5624     test_disp2((IUnknown*)col, &DIID_DispCPlugins, &IID_IHTMLPluginsCollection, "[object]");
5625 
5626     len = 0xdeadbeef;
5627     hres = IHTMLPluginsCollection_get_length(col, &len);
5628     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5629     ok(!len, "length = %d\n", len);
5630 
5631     hres = IHTMLPluginsCollection_refresh(col, VARIANT_FALSE);
5632     ok(hres == S_OK, "refresh failed: %08x\n", hres);
5633 
5634     hres = IHTMLPluginsCollection_refresh(col, VARIANT_TRUE);
5635     ok(hres == S_OK, "refresh failed: %08x\n", hres);
5636 
5637     ref = IHTMLPluginsCollection_Release(col);
5638     ok(!ref, "ref=%d\n", ref);
5639 
5640     IOmNavigator_Release(nav);
5641 }
5642 
test_mime_types_col(IOmNavigator * nav)5643 static void test_mime_types_col(IOmNavigator *nav)
5644 {
5645     IHTMLMimeTypesCollection *col, *col2;
5646     LONG length;
5647     ULONG ref;
5648     HRESULT hres;
5649 
5650     hres = IOmNavigator_get_mimeTypes(nav, &col);
5651     ok(hres == S_OK, "get_mimeTypes failed: %08x\n", hres);
5652 
5653     hres = IOmNavigator_get_mimeTypes(nav, &col2);
5654     ok(hres == S_OK, "get_mimeTypes failed: %08x\n", hres);
5655     ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n");
5656     IHTMLMimeTypesCollection_Release(col2);
5657 
5658     test_disp((IUnknown*)col, &IID_IHTMLMimeTypesCollection, "[object]");
5659 
5660     length = 0xdeadbeef;
5661     hres = IHTMLMimeTypesCollection_get_length(col, &length);
5662     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5663     ok(!length, "length = %d\n", length);
5664 
5665     ref = IHTMLMimeTypesCollection_Release(col);
5666     ok(!ref, "ref=%d\n", ref);
5667 }
5668 
5669 #define test_framebase_name(a,b) _test_framebase_name(__LINE__,a,b)
_test_framebase_name(unsigned line,IHTMLElement * elem,const char * name)5670 static void _test_framebase_name(unsigned line, IHTMLElement *elem, const char *name)
5671 {
5672     BSTR str = (void*)0xdeadbeef;
5673     IHTMLFrameBase *fbase;
5674     HRESULT hres;
5675 
5676     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
5677     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
5678 
5679     hres = IHTMLFrameBase_get_name(fbase, &str);
5680     ok_(__FILE__,line)(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
5681     if(name)
5682         ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
5683     else
5684         ok_(__FILE__,line)(!str, "name = %s, expected NULL\n", wine_dbgstr_w(str));
5685     SysFreeString(str);
5686 
5687     IHTMLFrameBase_Release(fbase);
5688 }
5689 
5690 #define test_framebase_put_name(a,b) _test_framebase_put_name(__LINE__,a,b)
_test_framebase_put_name(unsigned line,IHTMLElement * elem,const char * name)5691 static void _test_framebase_put_name(unsigned line, IHTMLElement *elem, const char *name)
5692 {
5693     IHTMLFrameBase *fbase;
5694     HRESULT hres;
5695     BSTR str;
5696 
5697     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
5698     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
5699 
5700     str = name ? a2bstr(name) : NULL;
5701     hres = IHTMLFrameBase_put_name(fbase, str);
5702     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
5703     SysFreeString(str);
5704 
5705     _test_framebase_name(line, elem, name);
5706     IHTMLFrameBase_Release(fbase);
5707 }
5708 
5709 #define test_framebase_src(a,b) _test_framebase_src(__LINE__,a,b)
_test_framebase_src(unsigned line,IHTMLElement * elem,const char * src)5710 static void _test_framebase_src(unsigned line, IHTMLElement *elem, const char *src)
5711 {
5712     BSTR str = (void*)0xdeadbeef;
5713     IHTMLFrameBase *fbase;
5714     HRESULT hres;
5715 
5716     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
5717     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
5718 
5719     hres = IHTMLFrameBase_get_src(fbase, &str);
5720     ok_(__FILE__,line)(hres == S_OK, "IHTMLFrameBase_get_src failed: 0x%08x\n", hres);
5721     if(src)
5722         ok_(__FILE__,line)(!strcmp_wa(str, src), "src = %s, expected %s\n", wine_dbgstr_w(str), src);
5723     else
5724         ok_(__FILE__,line)(!str, "src = %s, expected NULL\n", wine_dbgstr_w(str));
5725     SysFreeString(str);
5726 
5727     IHTMLFrameBase_Release(fbase);
5728 }
5729 
5730 #define test_framebase_marginheight(a,b) _test_framebase_marginheight(__LINE__,a,b)
_test_framebase_marginheight(unsigned line,IHTMLFrameBase * framebase,const char * exval)5731 static void _test_framebase_marginheight(unsigned line, IHTMLFrameBase *framebase, const char *exval)
5732 {
5733     VARIANT v;
5734     HRESULT hres;
5735 
5736     hres = IHTMLFrameBase_get_marginHeight(framebase, &v);
5737     ok_(__FILE__,line)(hres == S_OK, "get_marginHeight failed: %08x\n", hres);
5738     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(marginHeight) = %d\n", V_VT(&v));
5739     if(exval)
5740         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "marginHeight = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
5741     else
5742         ok_(__FILE__,line)(!V_BSTR(&v), "marginHeight = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
5743     VariantClear(&v);
5744 }
5745 
5746 #define set_framebase_marginheight(a,b) _set_framebase_marginheight(__LINE__,a,b)
_set_framebase_marginheight(unsigned line,IHTMLFrameBase * framebase,const char * val)5747 static void _set_framebase_marginheight(unsigned line, IHTMLFrameBase *framebase, const char *val)
5748 {
5749     VARIANT v;
5750     HRESULT hres;
5751 
5752     V_VT(&v) = VT_BSTR;
5753     V_BSTR(&v) = a2bstr(val);
5754     hres = IHTMLFrameBase_put_marginHeight(framebase, v);
5755     ok_(__FILE__,line)(hres == S_OK, "put_marginHeight failed: %08x\n", hres);
5756     VariantClear(&v);
5757 }
5758 
5759 #define test_framebase_marginwidth(a,b) _test_framebase_marginwidth(__LINE__,a,b)
_test_framebase_marginwidth(unsigned line,IHTMLFrameBase * framebase,const char * exval)5760 static void _test_framebase_marginwidth(unsigned line, IHTMLFrameBase *framebase, const char *exval)
5761 {
5762     VARIANT v;
5763     HRESULT hres;
5764 
5765     hres = IHTMLFrameBase_get_marginWidth(framebase, &v);
5766     ok_(__FILE__,line)(hres == S_OK, "get_marginWidth failed: %08x\n", hres);
5767     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(marginWidth) = %d\n", V_VT(&v));
5768     if(exval)
5769         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "marginWidth = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
5770     else
5771         ok_(__FILE__,line)(!V_BSTR(&v), "marginWidth = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
5772     VariantClear(&v);
5773 }
5774 
5775 #define set_framebase_marginwidth(a,b) _set_framebase_marginwidth(__LINE__,a,b)
_set_framebase_marginwidth(unsigned line,IHTMLFrameBase * framebase,const char * val)5776 static void _set_framebase_marginwidth(unsigned line, IHTMLFrameBase *framebase, const char *val)
5777 {
5778     VARIANT v;
5779     HRESULT hres;
5780 
5781     V_VT(&v) = VT_BSTR;
5782     V_BSTR(&v) = a2bstr(val);
5783     hres = IHTMLFrameBase_put_marginWidth(framebase, v);
5784     ok_(__FILE__,line)(hres == S_OK, "put_marginWidth failed: %08x\n", hres);
5785     VariantClear(&v);
5786 }
5787 
test_framebase(IUnknown * unk)5788 static void test_framebase(IUnknown *unk)
5789 {
5790     IHTMLFrameBase *fbase;
5791     BSTR str;
5792     HRESULT hres;
5793 
5794     /* get/put scrolling */
5795     hres = IUnknown_QueryInterface(unk, &IID_IHTMLFrameBase, (void**)&fbase);
5796     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
5797 
5798     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
5799     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
5800     ok(!strcmp_wa(str, "auto"), "get_scrolling should have given 'auto', gave: %s\n", wine_dbgstr_w(str));
5801     SysFreeString(str);
5802 
5803     str = a2bstr("no");
5804     hres = IHTMLFrameBase_put_scrolling(fbase, str);
5805     ok(hres == S_OK, "IHTMLFrameBase_put_scrolling failed: 0x%08x\n", hres);
5806     SysFreeString(str);
5807 
5808     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
5809     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
5810     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
5811     SysFreeString(str);
5812 
5813     str = a2bstr("junk");
5814     hres = IHTMLFrameBase_put_scrolling(fbase, str);
5815     ok(hres == E_INVALIDARG, "IHTMLFrameBase_put_scrolling should have failed "
5816             "with E_INVALIDARG, instead: 0x%08x\n", hres);
5817     SysFreeString(str);
5818 
5819     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
5820     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
5821     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
5822     SysFreeString(str);
5823 
5824     hres = IHTMLFrameBase_get_frameBorder(fbase, &str);
5825     ok(hres == S_OK, "get_frameBorder failed: %08x\n", hres);
5826     ok(!str, "frameBorder = %s\n", wine_dbgstr_w(str));
5827 
5828     str = a2bstr("1");
5829     hres = IHTMLFrameBase_put_frameBorder(fbase, str);
5830     ok(hres == S_OK, "put_frameBorder failed: %08x\n", hres);
5831     SysFreeString(str);
5832 
5833     hres = IHTMLFrameBase_get_frameBorder(fbase, &str);
5834     ok(hres == S_OK, "get_frameBorder failed: %08x\n", hres);
5835     ok(!strcmp_wa(str, "1"), "frameBorder = %s, expected \"1\"\n", wine_dbgstr_w(str));
5836 
5837     test_framebase_marginheight(fbase, NULL);
5838     set_framebase_marginheight(fbase, "1px");
5839     test_framebase_marginheight(fbase, "1");
5840 
5841     test_framebase_marginwidth(fbase, NULL);
5842     set_framebase_marginwidth(fbase, "2px");
5843     test_framebase_marginwidth(fbase, "2");
5844 
5845     IHTMLFrameBase_Release(fbase);
5846 }
5847 
5848 #define test_language_string(a,b) _test_language_string(__LINE__,a,b)
_test_language_string(unsigned line,const WCHAR * lang,LCID lcid)5849 static void _test_language_string(unsigned line, const WCHAR *lang, LCID lcid)
5850 {
5851     WCHAR buf[64];
5852     int res;
5853 
5854     if(pLCIDToLocaleName) {
5855         res = pLCIDToLocaleName(lcid, buf, sizeof(buf)/sizeof(WCHAR), 0);
5856         ok_(__FILE__,line)(res, "LCIDToLocaleName failed: %u\n", GetLastError());
5857         ok_(__FILE__,line)(!lstrcmpW(lang, buf), "lang = %s, expected %s\n", wine_dbgstr_w(lang), wine_dbgstr_w(buf));
5858     }else {
5859         win_skip("LCIDToLocaleName not available, unable to test language string\n");
5860         ok_(__FILE__,line)(lang != NULL, "lang == NULL\n");
5861     }
5862 }
5863 
5864 #define test_table_length(t,l)  _test_table_length(__LINE__,t,l)
_test_table_length(unsigned line,IHTMLTable * table,LONG expect)5865 static void _test_table_length(unsigned line, IHTMLTable *table, LONG expect)
5866 {
5867     IHTMLElementCollection *col;
5868     HRESULT hres;
5869     LONG len;
5870 
5871     hres = IHTMLTable_get_rows(table, &col);
5872     ok_(__FILE__,line)(hres == S_OK, "get_rows failed: %08x\n", hres);
5873     ok_(__FILE__,line)(col != NULL, "col = NULL\n");
5874     if (hres != S_OK || col == NULL)
5875         return;
5876     hres = IHTMLElementCollection_get_length(col, &len);
5877     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
5878     ok_(__FILE__,line)(len == expect, "Expect %d, got %d\n", expect, len);
5879 
5880     IHTMLElementCollection_Release(col);
5881 }
5882 
test_navigator(IHTMLDocument2 * doc)5883 static void test_navigator(IHTMLDocument2 *doc)
5884 {
5885     IHTMLWindow2 *window;
5886     IOmNavigator *navigator, *navigator2;
5887     VARIANT_BOOL b;
5888     char buf[512];
5889     DWORD size;
5890     ULONG ref;
5891     BSTR bstr;
5892     HRESULT hres;
5893 
5894     static const WCHAR v40[] = {'4','.','0'};
5895 
5896     hres = IHTMLDocument2_get_parentWindow(doc, &window);
5897     ok(hres == S_OK, "parentWidnow failed: %08x\n", hres);
5898 
5899     hres = IHTMLWindow2_get_navigator(window, &navigator);
5900     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
5901     ok(navigator != NULL, "navigator == NULL\n");
5902     test_disp2((IUnknown*)navigator, &DIID_DispHTMLNavigator, &IID_IOmNavigator, "[object]");
5903 
5904     hres = IHTMLWindow2_get_navigator(window, &navigator2);
5905     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
5906     ok(navigator != navigator2, "navigator2 != navihgator\n");
5907 
5908     IHTMLWindow2_Release(window);
5909     IOmNavigator_Release(navigator2);
5910 
5911     hres = IOmNavigator_get_appCodeName(navigator, &bstr);
5912     ok(hres == S_OK, "get_appCodeName failed: %08x\n", hres);
5913     ok(!strcmp_wa(bstr, "Mozilla"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
5914     SysFreeString(bstr);
5915 
5916     bstr = NULL;
5917     hres = IOmNavigator_get_appName(navigator, &bstr);
5918     ok(hres == S_OK, "get_appName failed: %08x\n", hres);
5919     ok(!strcmp_wa(bstr, "Microsoft Internet Explorer"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
5920     SysFreeString(bstr);
5921 
5922     bstr = NULL;
5923     hres = IOmNavigator_get_platform(navigator, &bstr);
5924     ok(hres == S_OK, "get_platform failed: %08x\n", hres);
5925     ok(!strcmp_wa(bstr, sizeof(void*) == 8 ? "Win64" : "Win32")
5926        || (sizeof(void*) == 8 && broken(!strcmp_wa(bstr, "Win32") /* IE6 */)), "unexpected platform %s\n", wine_dbgstr_w(bstr));
5927     SysFreeString(bstr);
5928 
5929     bstr = NULL;
5930     hres = IOmNavigator_get_cpuClass(navigator, &bstr);
5931     ok(hres == S_OK, "get_cpuClass failed: %08x\n", hres);
5932     ok(!strcmp_wa(bstr, sizeof(void*) == 8 ? "x64" : "x86"), "unexpected cpuClass %s\n", wine_dbgstr_w(bstr));
5933     SysFreeString(bstr);
5934 
5935     bstr = NULL;
5936     hres = IOmNavigator_get_appVersion(navigator, &bstr);
5937     ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
5938     ok(!memcmp(bstr, v40, sizeof(v40)), "appVersion is %s\n", wine_dbgstr_w(bstr));
5939     SysFreeString(bstr);
5940 
5941     bstr = NULL;
5942     hres = IOmNavigator_get_systemLanguage(navigator, &bstr);
5943     ok(hres == S_OK, "get_systemLanguage failed: %08x\n", hres);
5944     test_language_string(bstr, LOCALE_SYSTEM_DEFAULT);
5945     SysFreeString(bstr);
5946 
5947     if (pGetUserDefaultUILanguage)
5948     {
5949         bstr = NULL;
5950         hres = IOmNavigator_get_browserLanguage(navigator, &bstr);
5951         ok(hres == S_OK, "get_browserLanguage failed: %08x\n", hres);
5952         test_language_string(bstr, pGetUserDefaultUILanguage());
5953         SysFreeString(bstr);
5954     }
5955     else
5956         win_skip("GetUserDefaultUILanguage not available\n");
5957 
5958     bstr = NULL;
5959     hres = IOmNavigator_get_userLanguage(navigator, &bstr);
5960     ok(hres == S_OK, "get_userLanguage failed: %08x\n", hres);
5961     test_language_string(bstr, LOCALE_USER_DEFAULT);
5962     SysFreeString(bstr);
5963 
5964     hres = IOmNavigator_toString(navigator, NULL);
5965     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
5966 
5967     bstr = NULL;
5968     hres = IOmNavigator_toString(navigator, &bstr);
5969     ok(hres == S_OK, "toString failed: %08x\n", hres);
5970     ok(!strcmp_wa(bstr, "[object]"), "toString returned %s\n", wine_dbgstr_w(bstr));
5971     SysFreeString(bstr);
5972 
5973     b = 100;
5974     hres = IOmNavigator_get_onLine(navigator, &b);
5975     ok(hres == S_OK, "get_onLine failed: %08x\n", hres);
5976     ok(b == VARIANT_TRUE, "onLine = %x\n", b);
5977 
5978     size = sizeof(buf);
5979     hres = ObtainUserAgentString(0, buf, &size);
5980     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
5981 
5982     bstr = NULL;
5983     hres = IOmNavigator_get_userAgent(navigator, &bstr);
5984     ok(hres == S_OK, "get_userAgent failed: %08x\n", hres);
5985     ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf);
5986     SysFreeString(bstr);
5987 
5988     if(!strncmp(buf, "Mozilla/", 8)) {
5989         bstr = NULL;
5990         hres = IOmNavigator_get_appVersion(navigator, &bstr);
5991         ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
5992         ok(!strcmp_wa(bstr, buf+8), "appVersion returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf+8);
5993         SysFreeString(bstr);
5994     }else {
5995         skip("nonstandard user agent\n");
5996     }
5997 
5998     bstr = NULL;
5999     hres = IOmNavigator_get_appMinorVersion(navigator, &bstr);
6000     ok(hres == S_OK, "get_appMonorVersion failed: %08x\n", hres);
6001     ok(bstr != NULL, "appMinorVersion returned NULL\n");
6002     SysFreeString(bstr);
6003 
6004     test_mime_types_col(navigator);
6005 
6006     ref = IOmNavigator_Release(navigator);
6007     ok(!ref, "navigator should be destroyed here\n");
6008 }
6009 
test_screen(IHTMLWindow2 * window)6010 static void test_screen(IHTMLWindow2 *window)
6011 {
6012     IHTMLScreen *screen, *screen2;
6013     IDispatchEx *dispex;
6014     RECT work_area;
6015     LONG l, exl;
6016     HDC hdc;
6017     HRESULT hres;
6018 
6019     screen = NULL;
6020     hres = IHTMLWindow2_get_screen(window, &screen);
6021     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
6022     ok(screen != NULL, "screen == NULL\n");
6023 
6024     screen2 = NULL;
6025     hres = IHTMLWindow2_get_screen(window, &screen2);
6026     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
6027     ok(screen2 != NULL, "screen == NULL\n");
6028     ok(iface_cmp((IUnknown*)screen2, (IUnknown*)screen), "screen2 != screen\n");
6029     IHTMLScreen_Release(screen2);
6030 
6031     hres = IHTMLScreen_QueryInterface(screen, &IID_IDispatchEx, (void**)&dispex);
6032     ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres);
6033     if(SUCCEEDED(hres)) {
6034         test_disp((IUnknown*)screen, &DIID_DispHTMLScreen, "[object]");
6035         IDispatchEx_Release(dispex);
6036     }
6037 
6038     hdc = CreateICA("DISPLAY", NULL, NULL, NULL);
6039 
6040     exl = GetDeviceCaps(hdc, HORZRES);
6041     l = 0xdeadbeef;
6042     hres = IHTMLScreen_get_width(screen, &l);
6043     ok(hres == S_OK, "get_width failed: %08x\n", hres);
6044     ok(l == exl, "width = %d, expected %d\n", l, exl);
6045 
6046     exl = GetDeviceCaps(hdc, VERTRES);
6047     l = 0xdeadbeef;
6048     hres = IHTMLScreen_get_height(screen, &l);
6049     ok(hres == S_OK, "get_height failed: %08x\n", hres);
6050     ok(l == exl, "height = %d, expected %d\n", l, exl);
6051 
6052     exl = GetDeviceCaps(hdc, BITSPIXEL);
6053     l = 0xdeadbeef;
6054     hres = IHTMLScreen_get_colorDepth(screen, &l);
6055     ok(hres == S_OK, "get_height failed: %08x\n", hres);
6056     ok(l == exl, "height = %d, expected %d\n", l, exl);
6057 
6058     DeleteObject(hdc);
6059 
6060     SystemParametersInfoW(SPI_GETWORKAREA, 0, &work_area, 0);
6061 
6062     l = 0xdeadbeef;
6063     hres = IHTMLScreen_get_availHeight(screen, &l);
6064     ok(hres == S_OK, "get_availHeight failed: %08x\n", hres);
6065     ok(l == work_area.bottom-work_area.top, "availHeight = %d, expected %d\n", l, work_area.bottom-work_area.top);
6066 
6067     l = 0xdeadbeef;
6068     hres = IHTMLScreen_get_availWidth(screen, &l);
6069     ok(hres == S_OK, "get_availWidth failed: %08x\n", hres);
6070     ok(l == work_area.right-work_area.left, "availWidth = %d, expected %d\n", l, work_area.right-work_area.left);
6071 
6072     IHTMLScreen_Release(screen);
6073 }
6074 
test_default_selection(IHTMLDocument2 * doc)6075 static void test_default_selection(IHTMLDocument2 *doc)
6076 {
6077     IHTMLSelectionObject *selection;
6078     IHTMLTxtRange *range;
6079     IDispatch *disp;
6080     BSTR str;
6081     HRESULT hres;
6082 
6083     hres = IHTMLDocument2_get_selection(doc, &selection);
6084     ok(hres == S_OK, "get_selection failed: %08x\n", hres);
6085 
6086     hres = IHTMLSelectionObject_get_type(selection, &str);
6087     ok(hres == S_OK, "get_type failed: %08x\n", hres);
6088     ok(!strcmp_wa(str, "None"), "type = %s\n", wine_dbgstr_w(str));
6089     SysFreeString(str);
6090 
6091     hres = IHTMLSelectionObject_createRange(selection, &disp);
6092     IHTMLSelectionObject_Release(selection);
6093     ok(hres == S_OK, "createRange failed: %08x\n", hres);
6094 
6095     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTxtRange, (void**)&range);
6096     IDispatch_Release(disp);
6097     ok(hres == S_OK, "Could not get IHTMLTxtRange interface: %08x\n", hres);
6098 
6099     test_range_text(range, NULL);
6100     IHTMLTxtRange_Release(range);
6101 }
6102 
test_doc_elem(IHTMLDocument2 * doc)6103 static void test_doc_elem(IHTMLDocument2 *doc)
6104 {
6105     IHTMLDocument2 *doc_node, *owner_doc;
6106     IHTMLElement *elem;
6107     IHTMLDocument3 *doc3;
6108     HRESULT hres;
6109     BSTR bstr;
6110 
6111     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
6112     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
6113 
6114     hres = IHTMLDocument2_toString(doc, &bstr);
6115     ok(hres == S_OK, "toString failed: %08x\n", hres);
6116     ok(!strcmp_wa(bstr, "[object]"),
6117             "toString returned %s, expected [object]\n", wine_dbgstr_w(bstr));
6118     SysFreeString(bstr);
6119 
6120     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
6121     IHTMLDocument3_Release(doc3);
6122     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
6123 
6124     test_node_name((IUnknown*)elem, "HTML");
6125     test_elem_tag((IUnknown*)elem, "HTML");
6126 
6127     doc_node = get_doc_node(doc);
6128     owner_doc = get_owner_doc((IUnknown*)elem);
6129     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
6130     IHTMLDocument2_Release(owner_doc);
6131 
6132     owner_doc = get_owner_doc((IUnknown*)doc_node);
6133     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
6134     IHTMLDocument2_Release(doc_node);
6135 
6136     test_elem_client_rect((IUnknown*)elem);
6137 
6138     IHTMLElement_Release(elem);
6139 }
6140 
test_default_body(IHTMLBodyElement * body)6141 static void test_default_body(IHTMLBodyElement *body)
6142 {
6143     LONG l;
6144     BSTR bstr;
6145     HRESULT hres;
6146     VARIANT v;
6147 
6148     bstr = (void*)0xdeadbeef;
6149     hres = IHTMLBodyElement_get_background(body, &bstr);
6150     ok(hres == S_OK, "get_background failed: %08x\n", hres);
6151     ok(bstr == NULL, "bstr != NULL\n");
6152 
6153     l = elem_get_scroll_height((IUnknown*)body);
6154     ok(l != -1, "scrollHeight == -1\n");
6155     l = elem_get_scroll_width((IUnknown*)body);
6156     ok(l != -1, "scrollWidth == -1\n");
6157     l = elem_get_scroll_top((IUnknown*)body);
6158     ok(!l, "scrollTop = %d\n", l);
6159     elem_get_scroll_left((IUnknown*)body);
6160 
6161     test_elem_dir((IUnknown*)body, NULL);
6162     set_elem_dir((IUnknown*)body, "ltr");
6163 
6164     /* get_text tests */
6165     hres = IHTMLBodyElement_get_text(body, &v);
6166     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
6167     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
6168     ok(V_BSTR(&v) == NULL, "bstr != NULL\n");
6169 
6170     /* get_text - Invalid Text */
6171     V_VT(&v) = VT_BSTR;
6172     V_BSTR(&v) = a2bstr("Invalid");
6173     hres = IHTMLBodyElement_put_text(body, v);
6174     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
6175     VariantClear(&v);
6176 
6177     V_VT(&v) = VT_NULL;
6178     hres = IHTMLBodyElement_get_text(body, &v);
6179     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
6180     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
6181     ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v = %s, expected '#00a0d0'\n", wine_dbgstr_w(V_BSTR(&v)));
6182     VariantClear(&v);
6183 
6184     /* get_text - Valid Text */
6185     V_VT(&v) = VT_BSTR;
6186     V_BSTR(&v) = a2bstr("#FF0000");
6187     hres = IHTMLBodyElement_put_text(body, v);
6188     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
6189     VariantClear(&v);
6190 
6191     V_VT(&v) = VT_NULL;
6192     hres = IHTMLBodyElement_get_text(body, &v);
6193     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
6194     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
6195     ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v = %s, expected '#ff0000'\n", wine_dbgstr_w(V_BSTR(&v)));
6196     VariantClear(&v);
6197 }
6198 
6199 #define test_body_scroll(a,b) _test_body_scroll(__LINE__,a,b)
_test_body_scroll(unsigned line,IHTMLBodyElement * body,const char * ex)6200 static void _test_body_scroll(unsigned line, IHTMLBodyElement *body, const char *ex)
6201 {
6202     BSTR str;
6203     HRESULT hres;
6204 
6205     hres = IHTMLBodyElement_get_scroll(body, &str);
6206     ok_(__FILE__,line)(hres == S_OK, "get_scroll failed: %08x\n", hres);
6207     ok_(__FILE__,line)(ex ? !strcmp_wa(str, ex) : !str, "scroll = %s\n", wine_dbgstr_w(str));
6208     SysFreeString(str);
6209 }
6210 
6211 #define set_body_scroll(a,b) _set_body_scroll(__LINE__,a,b)
_set_body_scroll(unsigned line,IHTMLBodyElement * body,const char * val)6212 static void _set_body_scroll(unsigned line, IHTMLBodyElement *body, const char *val)
6213 {
6214     BSTR str = a2bstr(val);
6215     HRESULT hres;
6216 
6217     hres = IHTMLBodyElement_put_scroll(body, str);
6218     ok_(__FILE__,line)(hres == S_OK, "put_scroll failed: %08x\n", hres);
6219     SysFreeString(str);
6220 
6221     _test_body_scroll(line, body, val);
6222 }
6223 
test_body_funs(IHTMLBodyElement * body)6224 static void test_body_funs(IHTMLBodyElement *body)
6225 {
6226     VARIANT vbg, vDefaultbg;
6227     HRESULT hres;
6228 
6229     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
6230     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6231     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
6232     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
6233 
6234     V_VT(&vbg) = VT_BSTR;
6235     V_BSTR(&vbg) = a2bstr("red");
6236     hres = IHTMLBodyElement_put_bgColor(body, vbg);
6237     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6238     VariantClear(&vbg);
6239 
6240     hres = IHTMLBodyElement_get_bgColor(body, &vbg);
6241     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6242     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
6243     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
6244     VariantClear(&vbg);
6245 
6246     /* Restore Originial */
6247     hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg);
6248     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6249     VariantClear(&vDefaultbg);
6250 
6251     test_body_scroll(body, NULL);
6252     set_body_scroll(body, "yes");
6253     set_body_scroll(body, "no");
6254     set_body_scroll(body, "auto");
6255 }
6256 
test_history(IHTMLWindow2 * window)6257 static void test_history(IHTMLWindow2 *window)
6258 {
6259     IOmHistory *history, *history2;
6260     HRESULT hres;
6261 
6262     history = NULL;
6263     hres = IHTMLWindow2_get_history(window, &history);
6264     ok(hres == S_OK, "get_history failed: %08x\n", hres);
6265     ok(history != NULL, "history = NULL\n");
6266 
6267     test_disp2((IUnknown*)history, &DIID_DispHTMLHistory, &IID_IOmHistory, "[object]");
6268 
6269     history2 = NULL;
6270     hres = IHTMLWindow2_get_history(window, &history2);
6271     ok(hres == S_OK, "get_history failed: %08x\n", hres);
6272     ok(history2 != NULL, "history2 = NULL\n");
6273     ok(iface_cmp((IUnknown*)history, (IUnknown*)history2), "history != history2\n");
6274 
6275     IOmHistory_Release(history2);
6276     IOmHistory_Release(history);
6277 }
6278 
test_xmlhttprequest(IHTMLWindow5 * window)6279 static void test_xmlhttprequest(IHTMLWindow5 *window)
6280 {
6281     HRESULT hres;
6282     VARIANT var;
6283     IHTMLXMLHttpRequestFactory *factory;
6284     IHTMLXMLHttpRequest *xml;
6285 
6286     hres = IHTMLWindow5_get_XMLHttpRequest(window, &var);
6287     ok(hres == S_OK, "get_XMLHttpRequest failed: %08x\n", hres);
6288     ok(V_VT(&var) == VT_DISPATCH, "expect VT_DISPATCH, got %s\n", debugstr_variant(&var));
6289 
6290     factory = NULL;
6291     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLXMLHttpRequestFactory, (void**)&factory);
6292     ok(hres == S_OK, "QueryInterface(&IID_IHTMLXMLHttpRequestFactory) failed: %08x\n", hres);
6293     ok(factory != NULL, "factory == NULL\n");
6294 
6295     xml = NULL;
6296     hres = IHTMLXMLHttpRequestFactory_create(factory, &xml);
6297     ok(hres == S_OK, "create failed: %08x\n", hres);
6298     ok(xml != NULL, "xml == NULL\n");
6299     test_disp((IUnknown*)xml, &DIID_DispHTMLXMLHttpRequest, "[object]");
6300 
6301     IHTMLXMLHttpRequest_Release(xml);
6302     IHTMLXMLHttpRequestFactory_Release(factory);
6303     VariantClear(&var);
6304 }
6305 
test_window(IHTMLDocument2 * doc)6306 static void test_window(IHTMLDocument2 *doc)
6307 {
6308     IHTMLWindow2 *window, *window2, *self, *parent;
6309     IHTMLWindow5 *window5;
6310     IHTMLDocument2 *doc2 = NULL;
6311     IDispatch *disp;
6312     IUnknown *unk;
6313     VARIANT v;
6314     BSTR str;
6315     HRESULT hres;
6316 
6317     hres = IHTMLDocument2_get_parentWindow(doc, &window);
6318     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
6319     test_ifaces((IUnknown*)window, window_iids);
6320     hres = IHTMLWindow2_QueryInterface(window, &IID_ITravelLogClient, (void**)&unk);
6321     if(hres == S_OK)
6322         IUnknown_Release(unk);
6323     else
6324         win_skip("IID_ITravelLogClient not supported\n");
6325 
6326     test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, "[object]");
6327 
6328     hres = IHTMLWindow2_get_document(window, &doc2);
6329     ok(hres == S_OK, "get_document failed: %08x\n", hres);
6330     ok(doc2 != NULL, "doc2 == NULL\n");
6331 
6332     test_ifaces((IUnknown*)doc2, doc_node_iids);
6333     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
6334     test_class_info((IUnknown*)doc2);
6335 
6336     test_ifaces((IUnknown*)doc, doc_obj_iids);
6337     test_disp((IUnknown*)doc, &DIID_DispHTMLDocument, "[object]");
6338     test_class_info((IUnknown*)doc);
6339 
6340     unk = (void*)0xdeadbeef;
6341     hres = IHTMLDocument2_QueryInterface(doc2, &IID_ICustomDoc, (void**)&unk);
6342     ok(hres == E_NOINTERFACE, "QueryInterface(IID_ICustomDoc) returned: %08x\n", hres);
6343     ok(!unk, "unk = %p\n", unk);
6344 
6345     IHTMLDocument2_Release(doc2);
6346 
6347     hres = IHTMLWindow2_get_window(window, &window2);
6348     ok(hres == S_OK, "get_window failed: %08x\n", hres);
6349     ok(window2 != NULL, "window2 == NULL\n");
6350 
6351     hres = IHTMLWindow2_get_self(window, &self);
6352     ok(hres == S_OK, "get_self failed: %08x\n", hres);
6353     ok(window2 != NULL, "self == NULL\n");
6354 
6355     ok(self == window2, "self != window2\n");
6356 
6357     IHTMLWindow2_Release(window2);
6358 
6359     disp = NULL;
6360     hres = IHTMLDocument2_get_Script(doc, &disp);
6361     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
6362     ok(disp == (void*)window, "disp != window\n");
6363     IDispatch_Release(disp);
6364 
6365     hres = IHTMLWindow2_toString(window, NULL);
6366     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
6367 
6368     str = NULL;
6369     hres = IHTMLWindow2_toString(window, &str);
6370     ok(hres == S_OK, "toString failed: %08x\n", hres);
6371     ok(!strcmp_wa(str, "[object]") ||
6372        !strcmp_wa(str, "[object Window]") /* win7 ie9 */, "toString returned %s\n", wine_dbgstr_w(str));
6373     SysFreeString(str);
6374 
6375     V_VT(&v) = VT_ERROR;
6376     hres = IHTMLWindow2_get_opener(window, &v);
6377     ok(hres == S_OK, "get_opener failed: %08x\n", hres);
6378     ok(V_VT(&v) == VT_EMPTY, "V_VT(opener) = %d\n", V_VT(&v));
6379 
6380     parent = NULL;
6381     hres = IHTMLWindow2_get_parent(window, &parent);
6382     ok(hres == S_OK, "get_parent failed: %08x\n", hres);
6383     ok(parent != NULL, "parent == NULL\n");
6384     ok(parent == self, "parent != window\n");
6385     IHTMLWindow2_Release(parent);
6386     IHTMLWindow2_Release(self);
6387 
6388     test_window_name(window, NULL);
6389     set_window_name(window, "test");
6390     test_window_length(window, 0);
6391     test_screen(window);
6392     test_window_status(window);
6393     set_window_status(window, "Test!");
6394     test_history(window);
6395 
6396     hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5);
6397     if(SUCCEEDED(hres)) {
6398         ok(window5 != NULL, "window5 == NULL\n");
6399         test_xmlhttprequest(window5);
6400         IHTMLWindow5_Release(window5);
6401     }else {
6402         win_skip("IHTMLWindow5 not supported!\n");
6403     }
6404 
6405     IHTMLWindow2_Release(window);
6406 }
6407 
test_dom_implementation(IHTMLDocument2 * doc)6408 static void test_dom_implementation(IHTMLDocument2 *doc)
6409 {
6410     IHTMLDocument5 *doc5 = get_htmldoc5_iface((IUnknown*)doc);
6411     IHTMLDOMImplementation *dom_implementation;
6412     VARIANT_BOOL b;
6413     VARIANT v;
6414     BSTR str;
6415     HRESULT hres;
6416 
6417     hres = IHTMLDocument5_get_implementation(doc5, &dom_implementation);
6418     IHTMLDocument5_Release(doc5);
6419     ok(hres == S_OK, "get_implementation failed: %08x\n", hres);
6420     ok(dom_implementation != NULL, "dom_implementation == NULL\n");
6421 
6422     str = a2bstr("test");
6423     V_VT(&v) = VT_BSTR;
6424     V_BSTR(&v) = a2bstr("1.0");
6425     b = 100;
6426     hres = IHTMLDOMImplementation_hasFeature(dom_implementation, str, v, &b);
6427     SysFreeString(str);
6428     VariantClear(&v);
6429     ok(hres == S_OK, "hasFeature failed: %08x\n", hres);
6430     ok(!b, "hasFeature returned %x\n", b);
6431 
6432     IHTMLDOMImplementation_Release(dom_implementation);
6433 }
6434 
test_defaults(IHTMLDocument2 * doc)6435 static void test_defaults(IHTMLDocument2 *doc)
6436 {
6437     IHTMLStyleSheetsCollection *stylesheetcol;
6438     IHTMLCurrentStyle *cstyle;
6439     IHTMLBodyElement *body;
6440     IHTMLElement2 *elem2;
6441     IHTMLElement *elem;
6442     IHTMLStyle *style;
6443     VARIANT v;
6444     BSTR str;
6445     LONG l;
6446     VARIANT_BOOL b;
6447     HRESULT hres;
6448     IHTMLElementCollection *collection;
6449 
6450     elem = doc_get_body(doc);
6451 
6452     hres = IHTMLDocument2_get_images(doc, NULL);
6453     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
6454 
6455     hres = IHTMLDocument2_get_images(doc, &collection);
6456     ok(hres == S_OK, "get_images failed: %08x\n", hres);
6457     if(hres == S_OK)
6458     {
6459         test_elem_collection((IUnknown*)collection, NULL, 0);
6460         IHTMLElementCollection_Release(collection);
6461     }
6462 
6463     hres = IHTMLDocument2_get_applets(doc, NULL);
6464     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
6465 
6466     hres = IHTMLDocument2_get_applets(doc, &collection);
6467     ok(hres == S_OK, "get_applets failed: %08x\n", hres);
6468     if(hres == S_OK)
6469     {
6470         test_elem_collection((IUnknown*)collection, NULL, 0);
6471         IHTMLElementCollection_Release(collection);
6472     }
6473 
6474     hres = IHTMLDocument2_get_links(doc, NULL);
6475     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
6476 
6477     hres = IHTMLDocument2_get_links(doc, &collection);
6478     ok(hres == S_OK, "get_links failed: %08x\n", hres);
6479     if(hres == S_OK)
6480     {
6481         test_elem_collection((IUnknown*)collection, NULL, 0);
6482         IHTMLElementCollection_Release(collection);
6483     }
6484 
6485     hres = IHTMLDocument2_get_forms(doc, NULL);
6486     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
6487 
6488     hres = IHTMLDocument2_get_forms(doc, &collection);
6489     ok(hres == S_OK, "get_forms failed: %08x\n", hres);
6490     if(hres == S_OK)
6491     {
6492         test_elem_collection((IUnknown*)collection, NULL, 0);
6493         IHTMLElementCollection_Release(collection);
6494     }
6495 
6496     hres = IHTMLDocument2_get_anchors(doc, NULL);
6497     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
6498 
6499     hres = IHTMLDocument2_get_anchors(doc, &collection);
6500     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
6501     if(hres == S_OK)
6502     {
6503         test_elem_collection((IUnknown*)collection, NULL, 0);
6504         IHTMLElementCollection_Release(collection);
6505     }
6506 
6507     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
6508     ok(hres == S_OK, "Could not get IHTMBodyElement: %08x\n", hres);
6509     test_default_body(body);
6510     test_body_funs(body);
6511     IHTMLBodyElement_Release(body);
6512 
6513     test_elem_istextedit(elem, VARIANT_TRUE);
6514 
6515     hres = IHTMLElement_get_style(elem, &style);
6516     ok(hres == S_OK, "get_style failed: %08x\n", hres);
6517 
6518     test_disp((IUnknown*)style, &DIID_DispHTMLStyle, "[object]");
6519     test_ifaces((IUnknown*)style, style_iids);
6520     IHTMLStyle_Release(style);
6521 
6522     str = NULL;
6523     hres = IHTMLDocument2_get_charset(doc, &str);
6524     ok(hres == S_OK, "get_charset failed: %08x\n", hres);
6525     ok(str && *str, "charset is empty\n"); /* FIXME: better tests */
6526     SysFreeString(str);
6527 
6528     test_window(doc);
6529     test_compatmode(doc, "BackCompat");
6530     test_location(doc);
6531     test_navigator(doc);
6532     test_plugins_col(doc);
6533 
6534     elem2 = get_elem2_iface((IUnknown*)elem);
6535     hres = IHTMLElement2_get_currentStyle(elem2, &cstyle);
6536     ok(hres == S_OK, "get_currentStyle failed: %08x\n", hres);
6537     if(SUCCEEDED(hres)) {
6538         IUnknown *unk;
6539 
6540         test_disp((IUnknown*)cstyle, &DIID_DispHTMLCurrentStyle, "[object]");
6541         test_ifaces((IUnknown*)cstyle, cstyle_iids);
6542 
6543         hres = IHTMLCurrentStyle_QueryInterface(cstyle, &IID_IHTMLCurrentStyle4, (void**)&unk);
6544         if(SUCCEEDED(hres))
6545             IUnknown_Release(unk);
6546         else
6547         {
6548            /*IE6 doesn't have interface */
6549            win_skip("IID_IHTMLCurrentStyle4 not supported\n");
6550         }
6551 
6552         IHTMLCurrentStyle_Release(cstyle);
6553     }
6554     IHTMLElement2_Release(elem2);
6555 
6556     IHTMLElement_Release(elem);
6557 
6558     hres = IHTMLDocument2_get_styleSheets(doc, &stylesheetcol);
6559     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
6560 
6561     l = 0xdeadbeef;
6562     hres = IHTMLStyleSheetsCollection_get_length(stylesheetcol, &l);
6563     ok(hres == S_OK, "get_length failed: %08x\n", hres);
6564     ok(l == 0, "length = %d\n", l);
6565 
6566     IHTMLStyleSheetsCollection_Release(stylesheetcol);
6567 
6568     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFiltersCollection, (void**)&body);
6569     ok(hres == E_NOINTERFACE, "got interface IHTMLFiltersCollection\n");
6570 
6571     str = a2bstr("xxx");
6572     b = 100;
6573     V_VT(&v) = VT_EMPTY;
6574     hres = IHTMLDocument2_execCommand(doc, str, FALSE, v, &b);
6575     ok(hres == OLECMDERR_E_NOTSUPPORTED || hres == E_INVALIDARG,
6576        "execCommand failed: %08x, expected OLECMDERR_E_NOTSUPPORTED or E_INVALIDARG\n", hres);
6577     SysFreeString(str);
6578 
6579     str = a2bstr("respectvisibilityindesign");
6580     b = 100;
6581     V_VT(&v) = VT_BOOL;
6582     V_BOOL(&v) = VARIANT_TRUE;
6583     hres = IHTMLDocument2_execCommand(doc, str, FALSE, v, &b);
6584     ok(hres == S_OK, "execCommand failed: %08x, expected DRAGDROP_E_NOTREGISTERED\n", hres);
6585     SysFreeString(str);
6586 
6587     test_default_selection(doc);
6588     test_doc_title(doc, "");
6589     test_dom_implementation(doc);
6590 }
6591 
6592 #define test_button_name(a,b) _test_button_name(__LINE__,a,b)
_test_button_name(unsigned line,IHTMLElement * elem,const char * exname)6593 static void _test_button_name(unsigned line, IHTMLElement *elem, const char *exname)
6594 {
6595     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
6596     BSTR str;
6597     HRESULT hres;
6598 
6599     str = (void*)0xdeadbeef;
6600     hres = IHTMLButtonElement_get_name(button, &str);
6601     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
6602     if(exname)
6603         ok_(__FILE__,line)(!strcmp_wa(str, exname), "name = %s, expected %s\n", wine_dbgstr_w(str), exname);
6604     else
6605         ok_(__FILE__,line)(!str, "name = %s, expected NULL\n", wine_dbgstr_w(str));
6606     SysFreeString(str);
6607     IHTMLButtonElement_Release(button);
6608 }
6609 
6610 #define set_button_name(a,b) _set_button_name(__LINE__,a,b)
_set_button_name(unsigned line,IHTMLElement * elem,const char * name)6611 static void _set_button_name(unsigned line, IHTMLElement *elem, const char *name)
6612 {
6613     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
6614     BSTR str = a2bstr(name);
6615     HRESULT hres;
6616 
6617     hres = IHTMLButtonElement_put_name(button, str);
6618     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
6619     SysFreeString(str);
6620     IHTMLButtonElement_Release(button);
6621 
6622     _test_button_name(line, elem, name);
6623 }
6624 
6625 #define test_button_get_disabled(i,b) _test_button_get_disabled(__LINE__,i,b)
_test_button_get_disabled(unsigned line,IHTMLElement * elem,VARIANT_BOOL exb)6626 static void _test_button_get_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
6627 {
6628     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
6629     VARIANT_BOOL disabled = 100;
6630     HRESULT hres;
6631 
6632     hres = IHTMLButtonElement_get_disabled(button, &disabled);
6633     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
6634     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
6635     IHTMLButtonElement_Release(button);
6636 
6637     _test_elem3_get_disabled(line, (IUnknown*)elem, exb);
6638 }
6639 
6640 #define test_button_set_disabled(i,b) _test_button_set_disabled(__LINE__,i,b)
_test_button_set_disabled(unsigned line,IHTMLElement * elem,VARIANT_BOOL b)6641 static void _test_button_set_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL b)
6642 {
6643     IHTMLButtonElement *button = _get_button_iface(line, (IUnknown*)elem);
6644     HRESULT hres;
6645 
6646     hres = IHTMLButtonElement_put_disabled(button, b);
6647     ok_(__FILE__,line) (hres == S_OK, "put_disabled failed: %08x\n", hres);
6648     IHTMLButtonElement_Release(button);
6649 
6650     _test_button_get_disabled(line, elem, b);
6651 }
6652 
test_button_elem(IHTMLElement * elem)6653 static void test_button_elem(IHTMLElement *elem)
6654 {
6655     test_button_name(elem, NULL);
6656     set_button_name(elem, "button name");
6657 
6658     test_elem_istextedit(elem, VARIANT_TRUE);
6659 }
6660 
6661 #define test_tr_possess(e,r,l,i) _test_tr_possess(__LINE__,e,r,l,i)
_test_tr_possess(unsigned line,IHTMLElement * elem,IHTMLTableRow * row,LONG len,const char * id)6662 static void _test_tr_possess(unsigned line, IHTMLElement *elem,
6663                             IHTMLTableRow *row, LONG len, const char *id)
6664 {
6665     IHTMLElementCollection *col;
6666     IDispatch *disp;
6667     HRESULT hres;
6668     LONG lval;
6669     VARIANT var;
6670 
6671     hres = IHTMLTableRow_get_cells(row, &col);
6672     ok_(__FILE__, line)(hres == S_OK, "get_cells failed: %08x\n", hres);
6673     ok_(__FILE__, line)(col != NULL, "get_cells returned NULL\n");
6674 
6675     hres = IHTMLElementCollection_get_length(col, &lval);
6676     ok_(__FILE__, line)(hres == S_OK, "get length failed: %08x\n", hres);
6677     ok_(__FILE__, line)(lval == len, "expected len = %d, got %d\n", len, lval);
6678 
6679     V_VT(&var) = VT_BSTR;
6680     V_BSTR(&var) = a2bstr(id);
6681     hres = IHTMLElementCollection_tags(col, var, &disp);
6682     ok_(__FILE__, line)(hres == S_OK, "search by tags(%s) failed: %08x\n", id, hres);
6683     ok_(__FILE__, line)(disp != NULL, "disp == NULL\n");
6684 
6685     VariantClear(&var);
6686     IDispatch_Release(disp);
6687     IHTMLElementCollection_Release(col);
6688 }
6689 
test_tr_modify(IHTMLElement * elem,IHTMLTableRow * row)6690 static void test_tr_modify(IHTMLElement *elem, IHTMLTableRow *row)
6691 {
6692     HRESULT hres;
6693     IDispatch *disp;
6694     IHTMLTableCell *cell;
6695 
6696     hres = IHTMLTableRow_deleteCell(row, 0);
6697     ok(hres == S_OK, "deleteCell failed: %08x\n", hres);
6698     test_tr_possess(elem, row, 1, "td2");
6699 
6700     hres = IHTMLTableRow_insertCell(row, 0, &disp);
6701     ok(hres == S_OK, "insertCell failed: %08x\n", hres);
6702     ok(disp != NULL, "disp == NULL\n");
6703     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTableCell, (void **)&cell);
6704     ok(hres == S_OK, "Could not get IID_IHTMLTableCell interface: %08x\n", hres);
6705     ok(cell != NULL, "cell == NULL\n");
6706     if (SUCCEEDED(hres))
6707         IHTMLTableCell_Release(cell);
6708     test_tr_possess(elem, row, 2, "td2");
6709     IDispatch_Release(disp);
6710 }
6711 
test_tr_elem(IHTMLElement * elem)6712 static void test_tr_elem(IHTMLElement *elem)
6713 {
6714     IHTMLElementCollection *col;
6715     IHTMLTableRow *row;
6716     HRESULT hres;
6717     BSTR bstr;
6718     LONG lval;
6719     VARIANT vbg, vDefaultbg;
6720 
6721     static const elem_type_t cell_types[] = {ET_TD,ET_TD};
6722 
6723     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableRow, (void**)&row);
6724     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
6725     if(FAILED(hres))
6726         return;
6727 
6728     col = NULL;
6729     hres = IHTMLTableRow_get_cells(row, &col);
6730     ok(hres == S_OK, "get_cells failed: %08x\n", hres);
6731     ok(col != NULL, "get_cells returned NULL\n");
6732 
6733     test_elem_collection((IUnknown*)col, cell_types, sizeof(cell_types)/sizeof(*cell_types));
6734     IHTMLElementCollection_Release(col);
6735 
6736     bstr = a2bstr("left");
6737     hres = IHTMLTableRow_put_align(row, bstr);
6738     ok(hres == S_OK, "set_align failed: %08x\n", hres);
6739     SysFreeString(bstr);
6740 
6741     bstr = NULL;
6742     hres = IHTMLTableRow_get_align(row, &bstr);
6743     ok(hres == S_OK, "get_align failed: %08x\n", hres);
6744     ok(bstr != NULL, "get_align returned NULL\n");
6745     ok(!strcmp_wa(bstr, "left"), "get_align returned %s\n", wine_dbgstr_w(bstr));
6746     SysFreeString(bstr);
6747 
6748     bstr = a2bstr("top");
6749     hres = IHTMLTableRow_put_vAlign(row, bstr);
6750     ok(hres == S_OK, "set_valign failed: %08x\n", hres);
6751     SysFreeString(bstr);
6752 
6753     bstr = NULL;
6754     hres = IHTMLTableRow_get_vAlign(row, &bstr);
6755     ok(hres == S_OK, "get_valign failed: %08x\n", hres);
6756     ok(bstr != NULL, "get_valign returned NULL\n");
6757     ok(!strcmp_wa(bstr, "top"), "get_valign returned %s\n", wine_dbgstr_w(bstr));
6758     SysFreeString(bstr);
6759 
6760     lval = 0xdeadbeef;
6761     hres = IHTMLTableRow_get_rowIndex(row, &lval);
6762     ok(hres == S_OK, "get_rowIndex failed: %08x\n", hres);
6763     ok(lval == 1, "get_rowIndex returned %d\n", lval);
6764 
6765     lval = 0xdeadbeef;
6766     hres = IHTMLTableRow_get_sectionRowIndex(row, &lval);
6767     ok(hres == S_OK, "get_sectionRowIndex failed: %08x\n", hres);
6768     ok(lval == 1, "get_sectionRowIndex returned %d\n", lval);
6769 
6770     hres = IHTMLTableRow_get_bgColor(row, &vDefaultbg);
6771     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6772     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
6773     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
6774 
6775     V_VT(&vbg) = VT_BSTR;
6776     V_BSTR(&vbg) = a2bstr("red");
6777     hres = IHTMLTableRow_put_bgColor(row, vbg);
6778     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6779     VariantClear(&vbg);
6780 
6781     hres = IHTMLTableRow_get_bgColor(row, &vbg);
6782     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6783     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
6784     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
6785     VariantClear(&vbg);
6786 
6787     V_VT(&vbg) = VT_I4;
6788     V_I4(&vbg) = 0xff0000;
6789     hres = IHTMLTableRow_put_bgColor(row, vbg);
6790     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6791     VariantClear(&vbg);
6792 
6793     hres = IHTMLTableRow_get_bgColor(row, &vbg);
6794     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6795     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
6796     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
6797     VariantClear(&vbg);
6798 
6799     /* Restore Originial */
6800     hres = IHTMLTableRow_put_bgColor(row, vDefaultbg);
6801     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6802     VariantClear(&vDefaultbg);
6803 
6804     test_tr_modify(elem, row);
6805 
6806     IHTMLTableRow_Release(row);
6807 }
6808 
test_td_elem(IHTMLElement * elem)6809 static void test_td_elem(IHTMLElement *elem)
6810 {
6811     IHTMLTableCell *cell;
6812     HRESULT hres;
6813     LONG lval;
6814     BSTR str;
6815     VARIANT vbg, vDefaultbg;
6816 
6817     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableCell, (void**)&cell);
6818     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
6819     if(FAILED(hres))
6820         return;
6821 
6822     lval = 0xdeadbeef;
6823     hres = IHTMLTableCell_get_cellIndex(cell, &lval);
6824     ok(hres == S_OK, "get cellIndex failed: %08x\n", hres);
6825     ok(lval == 1, "Expected 1, got %d\n", lval);
6826 
6827     str = a2bstr("left");
6828     hres = IHTMLTableCell_put_align(cell, str);
6829     ok(hres == S_OK, "put_align failed: %08x\n", hres);
6830     SysFreeString(str);
6831 
6832     str = NULL;
6833     hres = IHTMLTableCell_get_align(cell, &str);
6834     ok(hres == S_OK, "get_align failed: %08x\n", hres);
6835     ok(str != NULL, "str is NULL\n");
6836     if (str != NULL && hres == S_OK) {
6837         ok(!strcmp_wa(str, "left"), "got %s\n", wine_dbgstr_w(str));
6838         SysFreeString(str);
6839     }
6840 
6841     hres = IHTMLTableCell_get_bgColor(cell, &vDefaultbg);
6842     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6843     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
6844     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
6845 
6846     V_VT(&vbg) = VT_BSTR;
6847     V_BSTR(&vbg) = a2bstr("red");
6848     hres = IHTMLTableCell_put_bgColor(cell, vbg);
6849     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6850     VariantClear(&vbg);
6851 
6852     hres = IHTMLTableCell_get_bgColor(cell, &vbg);
6853     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6854     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
6855     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
6856     VariantClear(&vbg);
6857 
6858     V_VT(&vbg) = VT_I4;
6859     V_I4(&vbg) = 0xff0000;
6860     hres = IHTMLTableCell_put_bgColor(cell, vbg);
6861     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6862     VariantClear(&vbg);
6863 
6864     hres = IHTMLTableCell_get_bgColor(cell, &vbg);
6865     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
6866     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
6867     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
6868     VariantClear(&vbg);
6869 
6870     /* Restore Originial */
6871     hres = IHTMLTableCell_put_bgColor(cell, vDefaultbg);
6872     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
6873     VariantClear(&vDefaultbg);
6874 
6875     IHTMLTableCell_Release(cell);
6876 }
6877 
test_label_elem(IHTMLElement * elem)6878 static void test_label_elem(IHTMLElement *elem)
6879 {
6880     IHTMLLabelElement *label;
6881     BSTR str;
6882     HRESULT hres;
6883 
6884     label = get_label_iface((IUnknown*)elem);
6885 
6886     str = NULL;
6887     hres = IHTMLLabelElement_get_htmlFor(label, &str);
6888     ok(hres == S_OK, "get_htmlFor failed: %08x\n", hres);
6889     ok(!strcmp_wa(str, "in"), "htmlFor = %s\n", wine_dbgstr_w(str));
6890     SysFreeString(str);
6891 
6892     str = a2bstr("");
6893     hres = IHTMLLabelElement_put_htmlFor(label, str);
6894     ok(hres == S_OK, "put_htmlFor failed: %08x\n", hres);
6895     SysFreeString(str);
6896 
6897     str = (void*)0xdeadbeef;
6898     hres = IHTMLLabelElement_get_htmlFor(label, &str);
6899     ok(hres == S_OK, "get_htmlFor failed: %08x\n", hres);
6900     ok(!strcmp_wa(str, ""), "htmlFor = %s\n", wine_dbgstr_w(str));
6901 
6902     str = a2bstr("abc");
6903     hres = IHTMLLabelElement_put_htmlFor(label, str);
6904     ok(hres == S_OK, "put_htmlFor failed: %08x\n", hres);
6905     SysFreeString(str);
6906 
6907     str = NULL;
6908     hres = IHTMLLabelElement_get_htmlFor(label, &str);
6909     ok(hres == S_OK, "get_htmlFor failed: %08x\n", hres);
6910     ok(!strcmp_wa(str, "abc"), "htmlFor = %s\n", wine_dbgstr_w(str));
6911     SysFreeString(str);
6912 
6913     IHTMLLabelElement_Release(label);
6914 }
6915 
6916 #define test_table_cell_spacing(a,b) _test_table_cell_spacing(__LINE__,a,b)
_test_table_cell_spacing(unsigned line,IHTMLTable * table,const char * exstr)6917 static void _test_table_cell_spacing(unsigned line, IHTMLTable *table, const char *exstr)
6918 {
6919     VARIANT v;
6920     HRESULT hres;
6921 
6922     V_VT(&v) = VT_ERROR;
6923     hres = IHTMLTable_get_cellSpacing(table, &v);
6924     ok_(__FILE__,line)(hres == S_OK, "get_cellSpacing failed: %08x\n", hres);
6925     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
6926     if(exstr)
6927         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exstr), "cellSpacing = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exstr);
6928     else
6929         ok_(__FILE__,line)(!V_BSTR(&v), "cellSpacing = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
6930     VariantClear(&v);
6931 }
6932 
6933 #define test_table_cell_padding(a,b) _test_table_cell_padding(__LINE__,a,b)
_test_table_cell_padding(unsigned line,IHTMLTable * table,const char * exstr)6934 static void _test_table_cell_padding(unsigned line, IHTMLTable *table, const char *exstr)
6935 {
6936     VARIANT v;
6937     HRESULT hres;
6938 
6939     V_VT(&v) = VT_ERROR;
6940     hres = IHTMLTable_get_cellPadding(table, &v);
6941     ok_(__FILE__,line)(hres == S_OK, "get_cellPadding failed: %08x\n", hres);
6942     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
6943     if(exstr)
6944         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exstr), "cellPadding = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exstr);
6945     else
6946         ok_(__FILE__,line)(!V_BSTR(&v), "cellPadding = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
6947     VariantClear(&v);
6948 }
6949 
test_table_modify(IHTMLTable * table)6950 static void test_table_modify(IHTMLTable *table)
6951 {
6952     IDispatch *disp;
6953     IHTMLTableRow *row;
6954     HRESULT hres;
6955     LONG index;
6956 
6957     test_table_length(table, 2);
6958 
6959     hres = IHTMLTable_insertRow(table, 0, &disp);
6960     ok(hres == S_OK, "insertRow failed: %08x\n", hres);
6961     ok(disp != NULL, "disp == NULL\n");
6962     test_table_length(table, 3);
6963     if (hres != S_OK || disp == NULL)
6964         return;
6965 
6966     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTableRow, (void**)&row);
6967     IDispatch_Release(disp);
6968 
6969     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
6970     ok(row != NULL, "row == NULL\n");
6971 
6972     index = 0xdeadbeef;
6973     hres = IHTMLTableRow_get_rowIndex(row, &index);
6974     ok(hres == S_OK, "get_rowIndex failed: %08x\n", hres);
6975     ok(index == 0, "index = %d, expected 0\n", index);
6976 
6977     IHTMLTableRow_Release(row);
6978 
6979     hres = IHTMLTable_deleteRow(table, 0);
6980     ok(hres == S_OK, "deleteRow failed: %08x\n", hres);
6981     test_table_length(table, 2);
6982 }
6983 
test_table_elem(IHTMLElement * elem)6984 static void test_table_elem(IHTMLElement *elem)
6985 {
6986     IHTMLElementCollection *col;
6987     IHTMLTable *table;
6988     IHTMLTable3 *table3;
6989     IHTMLDOMNode *node;
6990     VARIANT v;
6991     HRESULT hres;
6992     BSTR bstr;
6993     VARIANT vbg, vDefaultbg;
6994 
6995     static const elem_type_t row_types[] = {ET_TR,ET_TR};
6996     static const elem_type_t all_types[] = {ET_TBODY,ET_TR,ET_TR,ET_TD,ET_TD};
6997     static const elem_type_t tbodies_types[] = {ET_TBODY};
6998 
6999     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable, (void**)&table);
7000     ok(hres == S_OK, "Could not get IHTMLTable iface: %08x\n", hres);
7001     if(FAILED(hres))
7002         return;
7003 
7004     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable3, (void**)&table3);
7005     ok(hres == S_OK, "Could not get IHTMLTable3 iface: %08x\n", hres);
7006     if(FAILED(hres))
7007         return;
7008 
7009     col = NULL;
7010     hres = IHTMLTable_get_rows(table, &col);
7011     ok(hres == S_OK, "get_rows failed: %08x\n", hres);
7012     ok(col != NULL, "get_rows returned NULL\n");
7013 
7014     test_elem_collection((IUnknown*)col, row_types, sizeof(row_types)/sizeof(*row_types));
7015     IHTMLElementCollection_Release(col);
7016 
7017     test_elem_all((IUnknown*)table, all_types, sizeof(all_types)/sizeof(*all_types));
7018 
7019     node = clone_node((IUnknown*)table, VARIANT_TRUE);
7020     test_elem_tag((IUnknown*)node, "TABLE");
7021     test_elem_all((IUnknown*)node, all_types, sizeof(all_types)/sizeof(*all_types));
7022     IHTMLDOMNode_Release(node);
7023 
7024     node = clone_node((IUnknown*)table, VARIANT_FALSE);
7025     test_elem_tag((IUnknown*)node, "TABLE");
7026     test_elem_all((IUnknown*)node, NULL, 0);
7027     IHTMLDOMNode_Release(node);
7028 
7029     col = NULL;
7030     hres = IHTMLTable_get_tBodies(table, &col);
7031     ok(hres == S_OK, "get_tBodies failed: %08x\n", hres);
7032     ok(col != NULL, "get_tBodies returned NULL\n");
7033 
7034     test_elem_collection((IUnknown*)col, tbodies_types, sizeof(tbodies_types)/sizeof(*tbodies_types));
7035     IHTMLElementCollection_Release(col);
7036 
7037     test_table_cell_spacing(table, NULL);
7038 
7039     V_VT(&v) = VT_I4;
7040     V_I4(&v) = 10;
7041     hres = IHTMLTable_put_cellSpacing(table, v);
7042     ok(hres == S_OK, "put_cellSpacing = %08x\n", hres);
7043     test_table_cell_spacing(table, "10");
7044 
7045     V_VT(&v) = VT_BSTR;
7046     V_BSTR(&v) = a2bstr("11");
7047     hres = IHTMLTable_put_cellSpacing(table, v);
7048     ok(hres == S_OK, "put_cellSpacing = %08x\n", hres);
7049     test_table_cell_spacing(table, "11");
7050     VariantClear(&v);
7051 
7052     test_table_cell_padding(table, NULL);
7053 
7054     V_VT(&v) = VT_I4;
7055     V_I4(&v) = 10;
7056     hres = IHTMLTable_put_cellPadding(table, v);
7057     ok(hres == S_OK, "put_cellPadding = %08x\n", hres);
7058     test_table_cell_padding(table, "10");
7059 
7060     V_VT(&v) = VT_BSTR;
7061     V_BSTR(&v) = a2bstr("11");
7062     hres = IHTMLTable_put_cellPadding(table, v);
7063     ok(hres == S_OK, "put_cellPadding = %08x\n", hres);
7064     test_table_cell_padding(table, "11");
7065     VariantClear(&v);
7066 
7067     V_VT(&v) = VT_R8;
7068     V_R8(&v) = 5;
7069     hres = IHTMLTable_put_cellPadding(table, v);
7070     ok(hres == S_OK, "put_cellPadding = %08x\n", hres);
7071     test_table_cell_padding(table, "5");
7072 
7073     bstr = a2bstr("left");
7074     hres = IHTMLTable_put_align(table, bstr);
7075     ok(hres == S_OK, "set_align failed: %08x\n", hres);
7076     SysFreeString(bstr);
7077 
7078     bstr = NULL;
7079     hres = IHTMLTable_get_align(table, &bstr);
7080     ok(hres == S_OK, "get_align failed: %08x\n", hres);
7081     ok(bstr != NULL, "get_align returned NULL\n");
7082     ok(!strcmp_wa(bstr, "left"), "get_align returned %s\n", wine_dbgstr_w(bstr));
7083     SysFreeString(bstr);
7084 
7085     hres = IHTMLTable_get_bgColor(table, &vDefaultbg);
7086     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
7087     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
7088     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
7089 
7090     V_VT(&vbg) = VT_BSTR;
7091     V_BSTR(&vbg) = a2bstr("red");
7092     hres = IHTMLTable_put_bgColor(table, vbg);
7093     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
7094     VariantClear(&vbg);
7095 
7096     hres = IHTMLTable_get_bgColor(table, &vbg);
7097     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
7098     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
7099     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
7100     VariantClear(&vbg);
7101 
7102     V_VT(&vbg) = VT_I4;
7103     V_I4(&vbg) = 0xff0000;
7104     hres = IHTMLTable_put_bgColor(table, vbg);
7105     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
7106     VariantClear(&vbg);
7107 
7108     hres = IHTMLTable_get_bgColor(table, &vbg);
7109     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
7110     ok(V_VT(&vbg) == VT_BSTR, "V_VT(&vbg) != VT_BSTR\n");
7111     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
7112     VariantClear(&vbg);
7113 
7114     /* Restore Originial */
7115     hres = IHTMLTable_put_bgColor(table, vDefaultbg);
7116     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
7117     VariantClear(&vDefaultbg);
7118 
7119     V_VT(&v) = VT_BSTR;
7120     V_BSTR(&v) = a2bstr("11");
7121     hres = IHTMLTable_put_width(table, v);
7122     ok(hres == S_OK, "put_width = %08x\n", hres);
7123     VariantClear(&v);
7124     hres = IHTMLTable_get_width(table, &v);
7125     ok(hres == S_OK, "get_width = %08x\n", hres);
7126     ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7127     VariantClear(&v);
7128 
7129     V_VT(&v) = VT_BSTR;
7130     V_BSTR(&v) = a2bstr("11.9");
7131     hres = IHTMLTable_put_width(table, v);
7132     ok(hres == S_OK, "put_width = %08x\n", hres);
7133     VariantClear(&v);
7134     hres = IHTMLTable_get_width(table, &v);
7135     ok(hres == S_OK, "get_width = %08x\n", hres);
7136     ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7137     VariantClear(&v);
7138 
7139     V_VT(&v) = VT_BSTR;
7140     V_BSTR(&v) = a2bstr("40.2%");
7141     hres = IHTMLTable_put_width(table, v);
7142     ok(hres == S_OK, "put_width = %08x\n", hres);
7143     VariantClear(&v);
7144     hres = IHTMLTable_get_width(table, &v);
7145     ok(hres == S_OK, "get_width = %08x\n", hres);
7146     ok(!strcmp_wa(V_BSTR(&v), "40.2%"), "Expected 40.2%%, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7147     VariantClear(&v);
7148 
7149     V_VT(&v) = VT_I4;
7150     V_I4(&v) = 11;
7151     hres = IHTMLTable_put_width(table, v);
7152     ok(hres == S_OK, "put_width = %08x\n", hres);
7153     hres = IHTMLTable_get_width(table, &v);
7154     ok(hres == S_OK, "get_width = %08x\n", hres);
7155     ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7156     VariantClear(&v);
7157 
7158     V_VT(&v) = VT_R8;
7159     V_R8(&v) = 11.9;
7160     hres = IHTMLTable_put_width(table, v);
7161     ok(hres == S_OK, "put_width = %08x\n", hres);
7162     hres = IHTMLTable_get_width(table, &v);
7163     ok(hres == S_OK, "get_width = %08x\n", hres);
7164     ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7165     VariantClear(&v);
7166 
7167     bstr = a2bstr("box");
7168     hres = IHTMLTable_put_frame(table, bstr);
7169     ok(hres == S_OK, "put_frame = %08x\n", hres);
7170     SysFreeString(bstr);
7171     hres = IHTMLTable_get_frame(table, &bstr);
7172     ok(hres == S_OK, "get_frame = %08x\n", hres);
7173     ok(!strcmp_wa(bstr, "box"), "Expected box, got %s\n", wine_dbgstr_w(bstr));
7174     SysFreeString(bstr);
7175 
7176 	test_table_modify(table);
7177     bstr = a2bstr("summary");
7178     hres = IHTMLTable3_put_summary(table3, bstr);
7179     ok(hres == S_OK, "put_summary = %08x\n", hres);
7180     SysFreeString(bstr);
7181 
7182     hres = IHTMLTable3_get_summary(table3, &bstr);
7183     ok(hres == S_OK, "get_summary = %08x\n", hres);
7184     ok(!strcmp_wa(bstr, "summary"), "Expected summary, got %s\n", wine_dbgstr_w(bstr));
7185     SysFreeString(bstr);
7186 
7187     IHTMLTable3_Release(table3);
7188     IHTMLTable_Release(table);
7189 }
7190 
doc_write(IHTMLDocument2 * doc,BOOL ln,const char * text)7191 static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
7192 {
7193     SAFEARRAYBOUND dim;
7194     SAFEARRAY *sa;
7195     VARIANT *var;
7196     HRESULT hres;
7197 
7198     dim.lLbound = 0;
7199     dim.cElements = 1;
7200     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
7201     SafeArrayAccessData(sa, (void**)&var);
7202     V_VT(var) = VT_BSTR;
7203     V_BSTR(var) = a2bstr(text);
7204     SafeArrayUnaccessData(sa);
7205 
7206     if(ln)
7207         hres = IHTMLDocument2_writeln(doc, sa);
7208     else
7209         hres = IHTMLDocument2_write(doc, sa);
7210     ok(hres == S_OK, "write failed: %08x\n", hres);
7211 
7212     SafeArrayDestroy(sa);
7213 }
7214 
doc_complex_write(IHTMLDocument2 * doc)7215 static void doc_complex_write(IHTMLDocument2 *doc)
7216 {
7217     SAFEARRAYBOUND dim = {5, 0};
7218     SAFEARRAY *sa;
7219     VARIANT *args;
7220     HRESULT hres;
7221 
7222     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
7223     SafeArrayAccessData(sa, (void**)&args);
7224 
7225     V_VT(args) = VT_BSTR;
7226     V_BSTR(args) = a2bstr("<body i4val=\"");
7227     V_VT(args+1) = VT_I4;
7228     V_I4(args+1) = 4;
7229     V_VT(args+2) = VT_BSTR;
7230     V_BSTR(args+2) = a2bstr("\" r8val=\"");
7231     V_VT(args+3) = VT_R8;
7232     V_R8(args+3) = 3.14;
7233     V_VT(args+4) = VT_BSTR;
7234     V_BSTR(args+4) = a2bstr("\">");
7235     SafeArrayUnaccessData(sa);
7236 
7237     hres = IHTMLDocument2_write(doc, sa);
7238     ok(hres == S_OK, "write failed: %08x\n", hres);
7239 
7240     SafeArrayDestroy(sa);
7241 }
7242 
test_frame_doc(IUnknown * frame_elem,BOOL iframe)7243 static void test_frame_doc(IUnknown *frame_elem, BOOL iframe)
7244 {
7245     IHTMLDocument2 *window_doc, *elem_doc;
7246     IHTMLFrameElement3 *frame_elem3;
7247     IHTMLWindow2 *content_window;
7248     HRESULT hres;
7249 
7250     content_window = get_frame_content_window(frame_elem);
7251     test_ifaces((IUnknown*)content_window, window_iids);
7252     window_doc = get_window_doc(content_window);
7253     IHTMLWindow2_Release(content_window);
7254 
7255     elem_doc = get_elem_doc(frame_elem);
7256     ok(iface_cmp((IUnknown*)window_doc, (IUnknown*)elem_doc), "content_doc != elem_doc\n");
7257 
7258     if(!iframe) {
7259         hres = IUnknown_QueryInterface(frame_elem, &IID_IHTMLFrameElement3, (void**)&frame_elem3);
7260         if(SUCCEEDED(hres)) {
7261             IDispatch *disp = NULL;
7262 
7263             hres = IHTMLFrameElement3_get_contentDocument(frame_elem3, &disp);
7264             ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
7265             ok(disp != NULL, "contentDocument == NULL\n");
7266             ok(iface_cmp((IUnknown*)disp, (IUnknown*)window_doc), "contentDocument != contentWindow.document\n");
7267 
7268             IDispatch_Release(disp);
7269             IHTMLFrameElement3_Release(frame_elem3);
7270         }else {
7271             win_skip("IHTMLFrameElement3 not supported\n");
7272         }
7273     }
7274 
7275     IHTMLDocument2_Release(elem_doc);
7276     IHTMLDocument2_Release(window_doc);
7277 }
7278 
7279 #define test_iframe_height(a,b) _test_iframe_height(__LINE__,a,b)
_test_iframe_height(unsigned line,IHTMLElement * elem,const char * exval)7280 static void _test_iframe_height(unsigned line, IHTMLElement *elem, const char *exval)
7281 {
7282     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
7283     VARIANT v;
7284     HRESULT hres;
7285 
7286     hres = IHTMLIFrameElement2_get_height(iframe, &v);
7287     ok_(__FILE__,line)(hres == S_OK, "get_height failed: %08x\n", hres);
7288     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(height) = %d\n", V_VT(&v));
7289     if(exval)
7290         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "height = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
7291     else
7292         ok_(__FILE__,line)(!V_BSTR(&v), "height = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
7293     VariantClear(&v);
7294     IHTMLIFrameElement2_Release(iframe);
7295 }
7296 
7297 #define set_iframe_height(a,b) _set_iframe_height(__LINE__,a,b)
_set_iframe_height(unsigned line,IHTMLElement * elem,const char * val)7298 static void _set_iframe_height(unsigned line, IHTMLElement *elem, const char *val)
7299 {
7300     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
7301     VARIANT v;
7302     HRESULT hres;
7303 
7304     V_VT(&v) = VT_BSTR;
7305     V_BSTR(&v) = a2bstr(val);
7306     hres = IHTMLIFrameElement2_put_height(iframe, v);
7307     ok_(__FILE__,line)(hres == S_OK, "put_height failed: %08x\n", hres);
7308     VariantClear(&v);
7309     IHTMLIFrameElement2_Release(iframe);
7310 }
7311 
7312 #define test_iframe_width(a,b) _test_iframe_width(__LINE__,a,b)
_test_iframe_width(unsigned line,IHTMLElement * elem,const char * exval)7313 static void _test_iframe_width(unsigned line, IHTMLElement *elem, const char *exval)
7314 {
7315     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
7316     VARIANT v;
7317     HRESULT hres;
7318 
7319     hres = IHTMLIFrameElement2_get_width(iframe, &v);
7320     ok_(__FILE__,line)(hres == S_OK, "get_width failed: %08x\n", hres);
7321     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(width) = %d\n", V_VT(&v));
7322     if(exval)
7323         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "width = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
7324     else
7325         ok_(__FILE__,line)(!V_BSTR(&v), "width = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
7326     VariantClear(&v);
7327     IHTMLIFrameElement2_Release(iframe);
7328 }
7329 
7330 #define set_iframe_width(a,b) _set_iframe_width(__LINE__,a,b)
_set_iframe_width(unsigned line,IHTMLElement * elem,const char * val)7331 static void _set_iframe_width(unsigned line, IHTMLElement *elem, const char *val)
7332 {
7333     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
7334     VARIANT v;
7335     HRESULT hres;
7336 
7337     V_VT(&v) = VT_BSTR;
7338     V_BSTR(&v) = a2bstr(val);
7339     hres = IHTMLIFrameElement2_put_width(iframe, v);
7340     ok_(__FILE__,line)(hres == S_OK, "put_width failed: %08x\n", hres);
7341     VariantClear(&v);
7342     IHTMLIFrameElement2_Release(iframe);
7343 }
7344 
test_iframe_elem(IHTMLElement * elem)7345 static void test_iframe_elem(IHTMLElement *elem)
7346 {
7347     IHTMLDocument2 *content_doc, *owner_doc;
7348     IHTMLIFrameElement3 *iframe3;
7349     IHTMLElementCollection *col;
7350     IHTMLWindow2 *content_window;
7351     IHTMLElement *body;
7352     IDispatch *disp;
7353     VARIANT errv;
7354     BSTR str;
7355     HRESULT hres;
7356 
7357     static const elem_type_t all_types[] = {
7358         ET_HTML,
7359         ET_HEAD,
7360         ET_TITLE,
7361         ET_BODY,
7362         ET_BR
7363     };
7364 
7365     test_frame_doc((IUnknown*)elem, TRUE);
7366     test_framebase((IUnknown*)elem);
7367 
7368     content_window = get_frame_content_window((IUnknown*)elem);
7369     test_ifaces((IUnknown*)content_window, window_iids);
7370     test_window_length(content_window, 0);
7371 
7372     content_doc = get_window_doc(content_window);
7373     IHTMLWindow2_Release(content_window);
7374 
7375     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLIFrameElement3, (void**)&iframe3);
7376     if(SUCCEEDED(hres)) {
7377         hres = IHTMLIFrameElement3_get_contentDocument(iframe3, &disp);
7378         ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
7379         ok(iface_cmp((IUnknown*)content_doc, (IUnknown*)disp), "content_doc != disp\n");
7380         IDispatch_Release(disp);
7381 
7382         IHTMLIFrameElement3_Release(iframe3);
7383     }else {
7384         win_skip("IHTMLIFrameElement3 not supported\n");
7385     }
7386 
7387     test_iframe_height(elem, NULL);
7388     set_iframe_height(elem, "100px");
7389     set_iframe_height(elem, "50%");
7390     test_iframe_height(elem, "50%");
7391 
7392     test_iframe_width(elem, NULL);
7393     set_iframe_width(elem, "150px");
7394     set_iframe_width(elem, "70%");
7395     test_iframe_width(elem, "70%");
7396     test_framebase_src(elem, "about:blank");
7397 
7398     str = a2bstr("text/html");
7399     V_VT(&errv) = VT_ERROR;
7400     disp = NULL;
7401     hres = IHTMLDocument2_open(content_doc, str, errv, errv, errv, &disp);
7402     SysFreeString(str);
7403     ok(hres == S_OK, "open failed: %08x\n", hres);
7404     ok(disp != NULL, "disp == NULL\n");
7405     ok(iface_cmp((IUnknown*)disp, (IUnknown*)content_window), "disp != content_window\n");
7406     IDispatch_Release(disp);
7407 
7408     doc_write(content_doc, FALSE, "<html><head><title>test</title></head>");
7409     doc_complex_write(content_doc);
7410     doc_write(content_doc, TRUE, "<br />");
7411     doc_write(content_doc, TRUE, "</html>");
7412 
7413     hres = IHTMLDocument2_get_all(content_doc, &col);
7414     ok(hres == S_OK, "get_all failed: %08x\n", hres);
7415     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
7416     IHTMLElementCollection_Release(col);
7417 
7418     body = doc_get_body(content_doc);
7419     test_elem_attr(body, "i4val", "4");
7420     test_elem_attr(body, "r8val", "3.14");
7421     IHTMLElement_Release(body);
7422 
7423     hres = IHTMLDocument2_close(content_doc);
7424     ok(hres == S_OK, "close failed: %08x\n", hres);
7425 
7426     owner_doc = get_owner_doc((IUnknown*)content_doc);
7427     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
7428 
7429     IHTMLDocument2_Release(content_doc);
7430 }
7431 
7432 #define test_stylesheet_csstext(a,b,c) _test_stylesheet_csstext(__LINE__,a,b,c)
_test_stylesheet_csstext(unsigned line,IHTMLStyleSheet * stylesheet,const char * exstr,BOOL is_todo)7433 static void _test_stylesheet_csstext(unsigned line, IHTMLStyleSheet *stylesheet, const char *exstr, BOOL is_todo)
7434 {
7435     BSTR str;
7436     HRESULT hres;
7437 
7438     hres = IHTMLStyleSheet_get_cssText(stylesheet, &str);
7439     ok_(__FILE__,line)(hres == S_OK, "get_cssText failed: %08x\n", hres);
7440     if(!is_todo) {
7441         if(exstr)
7442             ok_(__FILE__,line)(is_prefix_wa(str, exstr), "cssText = %s\n", wine_dbgstr_w(str));
7443         else
7444             ok_(__FILE__,line)(!str, "cssText = %s\n", wine_dbgstr_w(str));
7445     }else todo_wine {
7446         if(exstr)
7447             ok_(__FILE__,line)(is_prefix_wa(str, exstr), "cssText = %s\n", wine_dbgstr_w(str));
7448         else
7449             ok_(__FILE__,line)(!str, "cssText = %s\n", wine_dbgstr_w(str));
7450     }
7451 
7452     SysFreeString(str);
7453 }
7454 
7455 #define set_stylesheet_csstext(a,b,c) _set_stylesheet_csstext(__LINE__,a,b,c)
_set_stylesheet_csstext(unsigned line,IHTMLStyleSheet * stylesheet,const char * csstext,BOOL is_todo)7456 static void _set_stylesheet_csstext(unsigned line, IHTMLStyleSheet *stylesheet, const char *csstext, BOOL is_todo)
7457 {
7458     BSTR str = a2bstr(csstext);
7459     HRESULT hres;
7460 
7461     hres = IHTMLStyleSheet_put_cssText(stylesheet, str);
7462     if(!is_todo)
7463         ok_(__FILE__,line)(hres == S_OK, "put_cssText failed: %08x\n", hres);
7464     else
7465         todo_wine ok_(__FILE__,line)(hres == S_OK, "put_cssText failed: %08x\n", hres);
7466     SysFreeString(str);
7467 }
7468 
test_stylesheet(IDispatch * disp)7469 static void test_stylesheet(IDispatch *disp)
7470 {
7471     IHTMLStyleSheetRulesCollection *col = NULL;
7472     IHTMLStyleSheet *stylesheet;
7473     HRESULT hres;
7474     BSTR href;
7475 
7476     test_disp2((IUnknown*)disp, &DIID_DispHTMLStyleSheet, &IID_IHTMLStyleSheet, "[object]");
7477 
7478     hres = IDispatch_QueryInterface(disp, &IID_IHTMLStyleSheet, (void**)&stylesheet);
7479     ok(hres == S_OK, "Could not get IHTMLStyleSheet: %08x\n", hres);
7480 
7481     hres = IHTMLStyleSheet_get_rules(stylesheet, &col);
7482     ok(hres == S_OK, "get_rules failed: %08x\n", hres);
7483     ok(col != NULL, "col == NULL\n");
7484 
7485     test_disp2((IUnknown*)col, &DIID_DispHTMLStyleSheetRulesCollection, &IID_IHTMLStyleSheetRulesCollection, "[object]");
7486     IHTMLStyleSheetRulesCollection_Release(col);
7487 
7488     href = (void*)0xdeadbeef;
7489     hres = IHTMLStyleSheet_get_href(stylesheet, &href);
7490     ok(hres == S_OK, "get_href failed: %08x\n", hres);
7491     ok(href == NULL, "got href != NULL\n");
7492     SysFreeString(href);
7493 
7494     test_stylesheet_csstext(stylesheet, ".body {", FALSE);
7495     set_stylesheet_csstext(stylesheet, ".div { margin-right: 1px; }\n.body { margin-right: 2px; }", TRUE);
7496     test_stylesheet_csstext(stylesheet, ".div {", TRUE);
7497     set_stylesheet_csstext(stylesheet, "", FALSE);
7498     test_stylesheet_csstext(stylesheet, NULL, FALSE);
7499     set_stylesheet_csstext(stylesheet, ".div { margin-right: 1px; }", FALSE);
7500     test_stylesheet_csstext(stylesheet, ".div {", FALSE);
7501 
7502     IHTMLStyleSheet_Release(stylesheet);
7503 }
7504 
test_stylesheets(IHTMLDocument2 * doc)7505 static void test_stylesheets(IHTMLDocument2 *doc)
7506 {
7507     IHTMLStyleSheetsCollection *col = NULL;
7508     VARIANT idx, res;
7509     LONG len = 0;
7510     HRESULT hres;
7511 
7512     hres = IHTMLDocument2_get_styleSheets(doc, &col);
7513     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
7514     ok(col != NULL, "col == NULL\n");
7515 
7516     test_disp2((IUnknown*)col, &DIID_DispHTMLStyleSheetsCollection, &IID_IHTMLStyleSheetsCollection, "[object]");
7517 
7518     hres = IHTMLStyleSheetsCollection_get_length(col, &len);
7519     ok(hres == S_OK, "get_length failed: %08x\n", hres);
7520     ok(len == 1, "len=%d\n", len);
7521 
7522     VariantInit(&res);
7523     V_VT(&idx) = VT_I4;
7524     V_I4(&idx) = 0;
7525 
7526     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
7527     ok(hres == S_OK, "item failed: %08x\n", hres);
7528     ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
7529     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
7530     test_stylesheet(V_DISPATCH(&res));
7531     VariantClear(&res);
7532 
7533     V_VT(&res) = VT_I4;
7534     V_VT(&idx) = VT_I4;
7535     V_I4(&idx) = 1;
7536 
7537     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
7538     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
7539     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
7540     VariantClear(&res);
7541 
7542     IHTMLStyleSheetsCollection_Release(col);
7543 }
7544 
test_child_col_disp(IHTMLDOMChildrenCollection * col)7545 static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
7546 {
7547     IDispatchEx *dispex;
7548     IHTMLDOMNode *node;
7549     DISPPARAMS dp = {NULL, NULL, 0, 0};
7550     VARIANT var;
7551     EXCEPINFO ei;
7552     LONG type;
7553     DISPID id;
7554     BSTR bstr;
7555     HRESULT hres;
7556 
7557     static const WCHAR w0[] = {'0',0};
7558     static const WCHAR w100[] = {'1','0','0',0};
7559 
7560     hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
7561     ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
7562 
7563     bstr = SysAllocString(w0);
7564     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
7565     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
7566     SysFreeString(bstr);
7567 
7568     VariantInit(&var);
7569     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
7570     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
7571     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
7572     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
7573     node = get_node_iface((IUnknown*)V_DISPATCH(&var));
7574     type = get_node_type((IUnknown*)node);
7575     ok(type == 3, "type=%d\n", type);
7576     IHTMLDOMNode_Release(node);
7577     VariantClear(&var);
7578 
7579     bstr = SysAllocString(w100);
7580     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
7581     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
7582     SysFreeString(bstr);
7583 
7584     IDispatchEx_Release(dispex);
7585 }
7586 
test_enum_children(IUnknown * unk,unsigned len)7587 static void test_enum_children(IUnknown *unk, unsigned len)
7588 {
7589     IEnumVARIANT *enum_var;
7590     ULONG i, fetched;
7591     VARIANT v;
7592     HRESULT hres;
7593 
7594     hres = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enum_var);
7595     ok(hres == S_OK, "Could not get IEnumVARIANT iface: %08x\n", hres);
7596 
7597     for(i=0; i<len; i++) {
7598         fetched = 0;
7599         V_VT(&v) = VT_ERROR;
7600         hres = IEnumVARIANT_Next(enum_var, 1, &v, i ? &fetched : NULL);
7601         ok(hres == S_OK, "Next failed: %08x\n", hres);
7602         if(i)
7603             ok(fetched == 1, "fetched = %d\n", fetched);
7604         ok(V_VT(&v) == VT_DISPATCH && V_DISPATCH(&v), "V_VT(v) = %d\n", V_VT(&v));
7605         IDispatch_Release(V_DISPATCH(&v));
7606     }
7607 
7608     fetched = 0xdeadbeef;
7609     V_VT(&v) = VT_BOOL;
7610     hres = IEnumVARIANT_Next(enum_var, 1, &v, &fetched);
7611     ok(hres == S_FALSE, "Next returned %08x, expected S_FALSE\n", hres);
7612     ok(fetched == 0, "fetched = %d\n", fetched);
7613     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
7614 
7615     hres = IEnumVARIANT_Reset(enum_var);
7616     ok(hres == S_OK, "Reset failed: %08x\n", hres);
7617 
7618     fetched = 0xdeadbeef;
7619     V_VT(&v) = VT_BOOL;
7620     hres = IEnumVARIANT_Next(enum_var, 0, &v, &fetched);
7621     ok(hres == S_OK, "Next returned %08x, expected S_FALSE\n", hres);
7622     ok(fetched == 0, "fetched = %d\n", fetched);
7623     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
7624 
7625     hres = IEnumVARIANT_Skip(enum_var, len > 2 ? len-2 : 0);
7626     ok(hres == S_OK, "Skip failed: %08x\n", hres);
7627 
7628     hres = IEnumVARIANT_Reset(enum_var);
7629     ok(hres == S_OK, "Reset failed: %08x\n", hres);
7630 
7631     hres = IEnumVARIANT_Skip(enum_var, len+1);
7632     ok(hres == S_FALSE, "Skip failed: %08x\n", hres);
7633 
7634     IEnumVARIANT_Release(enum_var);
7635 }
7636 
test_elems(IHTMLDocument2 * doc)7637 static void test_elems(IHTMLDocument2 *doc)
7638 {
7639     IHTMLElementCollection *col;
7640     IHTMLDOMChildrenCollection *child_col;
7641     IHTMLElement *elem, *elem2, *elem3;
7642     IHTMLDOMNode *node, *node2;
7643     IHTMLWindow2 *window;
7644     IDispatch *disp;
7645     LONG type;
7646     HRESULT hres;
7647     IHTMLElementCollection *collection;
7648     IHTMLDocument3 *doc3;
7649     BSTR str;
7650 
7651     static const elem_type_t all_types[] = {
7652         ET_HTML,
7653         ET_HEAD,
7654         ET_TITLE,
7655         ET_STYLE,
7656         ET_META,
7657         ET_LINK,
7658         ET_BODY,
7659         ET_COMMENT,
7660         ET_A,
7661         ET_LABEL,
7662         ET_INPUT,
7663         ET_BUTTON,
7664         ET_SELECT,
7665         ET_OPTION,
7666         ET_OPTION,
7667         ET_TEXTAREA,
7668         ET_TABLE,
7669         ET_TBODY,
7670         ET_TR,
7671         ET_TR,
7672         ET_TD,
7673         ET_TD,
7674         ET_SCRIPT,
7675         ET_TEST,
7676         ET_OBJECT,
7677         ET_EMBED,
7678         ET_IMG,
7679         ET_IFRAME,
7680         ET_FORM,
7681         ET_DIV
7682     };
7683 
7684     static const elem_type_t item_types[] = {
7685         ET_A,
7686         ET_OPTION,
7687         ET_TEXTAREA
7688     };
7689 
7690     hres = IHTMLDocument2_get_all(doc, &col);
7691     ok(hres == S_OK, "get_all failed: %08x\n", hres);
7692     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
7693     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
7694 
7695     elem = get_elem_col_item_idx(col, 0);
7696     test_elem_source_index(elem, 0);
7697     IHTMLElement_Release(elem);
7698 
7699     elem = get_elem_col_item_idx(col, 3);
7700     test_elem_source_index(elem, 3);
7701     IHTMLElement_Release(elem);
7702 
7703     IHTMLElementCollection_Release(col);
7704 
7705     hres = IHTMLDocument2_get_images(doc, &collection);
7706     ok(hres == S_OK, "get_images failed: %08x\n", hres);
7707     if(hres == S_OK)
7708     {
7709         static const elem_type_t images_types[] = {ET_IMG};
7710         test_elem_collection((IUnknown*)collection, images_types, 1);
7711 
7712         IHTMLElementCollection_Release(collection);
7713     }
7714 
7715     hres = IHTMLDocument2_get_links(doc, &collection);
7716     ok(hres == S_OK, "get_links failed: %08x\n", hres);
7717     if(hres == S_OK)
7718     {
7719         static const elem_type_t images_types[] = {ET_A};
7720         test_elem_collection((IUnknown*)collection, images_types, 1);
7721 
7722         IHTMLElementCollection_Release(collection);
7723     }
7724 
7725     hres = IHTMLDocument2_get_anchors(doc, &collection);
7726     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
7727     if(hres == S_OK)
7728     {
7729         static const elem_type_t anchor_types[] = {ET_A};
7730         test_elem_collection((IUnknown*)collection, anchor_types, 1);
7731 
7732         IHTMLElementCollection_Release(collection);
7733     }
7734 
7735     hres = IHTMLDocument2_get_scripts(doc, &collection);
7736     ok(hres == S_OK, "get_scripts failed: %08x\n", hres);
7737     if(hres == S_OK) {
7738         static const elem_type_t script_types[] = {ET_SCRIPT};
7739         test_elem_collection((IUnknown*)collection, script_types, 1);
7740         IHTMLElementCollection_Release(collection);
7741     }
7742 
7743     test_plugins_col(doc);
7744 
7745     elem = get_doc_elem(doc);
7746     test_elem_istextedit(elem, VARIANT_FALSE);
7747     test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1);
7748     IHTMLElement_Release(elem);
7749 
7750     get_elem_by_id(doc, "xxx", FALSE);
7751     elem = get_doc_elem_by_id(doc, "xxx");
7752     ok(!elem, "elem != NULL\n");
7753 
7754     elem = get_doc_elem_by_id(doc, "s");
7755     ok(elem != NULL, "elem == NULL\n");
7756     if(elem) {
7757         test_elem_type((IUnknown*)elem, ET_SELECT);
7758         test_elem_attr(elem, "xxx", NULL);
7759         test_elem_attr(elem, "id", "s");
7760         test_elem_class((IUnknown*)elem, NULL);
7761         test_elem_set_class((IUnknown*)elem, "cl");
7762         test_elem_set_class((IUnknown*)elem, NULL);
7763         test_elem_tabindex((IUnknown*)elem, 0);
7764         test_elem_set_tabindex((IUnknown*)elem, 1);
7765         test_elem_filters((IUnknown*)elem);
7766         test_elem_istextedit(elem, VARIANT_FALSE);
7767 
7768         node = test_node_get_parent((IUnknown*)elem);
7769         ok(node != NULL, "node == NULL\n");
7770         test_node_name((IUnknown*)node, "BODY");
7771         node2 = test_node_get_parent((IUnknown*)node);
7772         IHTMLDOMNode_Release(node);
7773         ok(node2 != NULL, "node == NULL\n");
7774         test_node_name((IUnknown*)node2, "HTML");
7775         node = test_node_get_parent((IUnknown*)node2);
7776         IHTMLDOMNode_Release(node2);
7777         ok(node != NULL, "node == NULL\n");
7778         if (node)
7779         {
7780             test_node_name((IUnknown*)node, "#document");
7781             type = get_node_type((IUnknown*)node);
7782             ok(type == 9, "type=%d, expected 9\n", type);
7783             node2 = test_node_get_parent((IUnknown*)node);
7784             IHTMLDOMNode_Release(node);
7785             ok(node2 == NULL, "node != NULL\n");
7786         }
7787 
7788         elem2 = test_elem_get_parent((IUnknown*)elem);
7789         ok(elem2 != NULL, "elem2 == NULL\n");
7790         test_node_name((IUnknown*)elem2, "BODY");
7791 
7792         elem3 = test_elem_get_parent((IUnknown*)elem2);
7793         ok(elem3 != NULL, "elem3 == NULL\n");
7794         test_node_name((IUnknown*)elem3, "HTML");
7795 
7796         test_elem_contains(elem3, elem2, VARIANT_TRUE);
7797         test_elem_contains(elem3, elem, VARIANT_TRUE);
7798         test_elem_contains(elem2, elem, VARIANT_TRUE);
7799         test_elem_contains(elem2, elem3, VARIANT_FALSE);
7800         test_elem_contains(elem, elem3, VARIANT_FALSE);
7801         test_elem_contains(elem, elem2, VARIANT_FALSE);
7802         test_elem_contains(elem, elem, VARIANT_TRUE);
7803         test_elem_contains(elem, NULL, VARIANT_FALSE);
7804         IHTMLElement_Release(elem2);
7805 
7806         elem2 = test_elem_get_parent((IUnknown*)elem3);
7807         ok(elem2 == NULL, "elem2 != NULL\n");
7808         test_elem_source_index(elem3, 0);
7809         IHTMLElement_Release(elem3);
7810 
7811         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2, NULL);
7812         test_elem_getelembytag((IUnknown*)elem, ET_SELECT, 0, NULL);
7813         test_elem_getelembytag((IUnknown*)elem, ET_HTML, 0, NULL);
7814 
7815         test_elem_innertext(elem, "opt1opt2");
7816 
7817         IHTMLElement_Release(elem);
7818     }
7819 
7820     elem = get_elem_by_id(doc, "s", TRUE);
7821     if(elem) {
7822         IHTMLSelectElement *select = get_select_iface((IUnknown*)elem);
7823         IHTMLDocument2 *doc_node, *elem_doc;
7824 
7825         test_select_elem(select);
7826 
7827         test_elem_istextedit(elem, VARIANT_FALSE);
7828         test_elem_title((IUnknown*)select, NULL);
7829         test_elem_set_title((IUnknown*)select, "Title");
7830         test_elem_title((IUnknown*)select, "Title");
7831         test_elem_offset((IUnknown*)select, "BODY");
7832         test_elem_bounding_client_rect((IUnknown*)select);
7833 
7834         node = get_first_child((IUnknown*)select);
7835         ok(node != NULL, "node == NULL\n");
7836         if(node) {
7837             test_elem_type((IUnknown*)node, ET_OPTION);
7838             IHTMLDOMNode_Release(node);
7839         }
7840 
7841         type = get_node_type((IUnknown*)select);
7842         ok(type == 1, "type=%d\n", type);
7843 
7844         IHTMLSelectElement_Release(select);
7845 
7846         elem_doc = get_elem_doc((IUnknown*)elem);
7847 
7848         doc_node = get_doc_node(doc);
7849         ok(iface_cmp((IUnknown*)elem_doc, (IUnknown*)doc_node), "disp != doc\n");
7850         IHTMLDocument2_Release(doc_node);
7851         IHTMLDocument2_Release(elem_doc);
7852 
7853         IHTMLElement_Release(elem);
7854     }
7855 
7856     elem = get_elem_by_id(doc, "sc", TRUE);
7857     if(elem) {
7858         IHTMLScriptElement *script;
7859         BSTR type;
7860 
7861         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLScriptElement, (void**)&script);
7862         ok(hres == S_OK, "Could not get IHTMLScriptElement interface: %08x\n", hres);
7863 
7864         test_elem_language(elem, NULL);
7865         test_elem_istextedit(elem, VARIANT_FALSE);
7866 
7867         if(hres == S_OK)
7868         {
7869             VARIANT_BOOL vb;
7870 
7871             hres = IHTMLScriptElement_put_type (script, NULL);
7872             ok(hres == S_OK, "put_type failed: %08x\n", hres);
7873             hres = IHTMLScriptElement_get_type(script, &type);
7874             ok(hres == S_OK, "get_type failed: %08x\n", hres);
7875             ok(type == NULL, "Unexpected type %s\n", wine_dbgstr_w(type));
7876 
7877             type = a2bstr("text/javascript");
7878             hres = IHTMLScriptElement_put_type (script, type);
7879             ok(hres == S_OK, "put_type failed: %08x\n", hres);
7880             SysFreeString(type);
7881             hres = IHTMLScriptElement_get_type(script, &type);
7882             ok(hres == S_OK, "get_type failed: %08x\n", hres);
7883             ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type));
7884             SysFreeString(type);
7885 
7886             test_script_text(script, "<!--\nfunction Testing() {}\n// -->\n");
7887 
7888             /* test defer */
7889             hres = IHTMLScriptElement_put_defer(script, VARIANT_TRUE);
7890             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
7891 
7892             hres = IHTMLScriptElement_get_defer(script, &vb);
7893             ok(hres == S_OK, "get_defer failed: %08x\n", hres);
7894             ok(vb == VARIANT_TRUE, "get_defer result is %08x\n", hres);
7895 
7896             hres = IHTMLScriptElement_put_defer(script, VARIANT_FALSE);
7897             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
7898 
7899             str = (BSTR)0xdeadbeef;
7900             hres = IHTMLScriptElement_get_src(script, &str);
7901             ok(hres == S_OK, "get_src failed: %08x\n", hres);
7902             ok(!str, "src = %s\n", wine_dbgstr_w(str));
7903         }
7904 
7905         IHTMLScriptElement_Release(script);
7906 
7907         set_elem_language(elem, "vbscript");
7908         set_elem_language(elem, "xxx");
7909     }
7910 
7911     elem = get_elem_by_id(doc, "in", TRUE);
7912     if(elem) {
7913         IHTMLInputElement *input;
7914 
7915         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLInputElement, (void**)&input);
7916         ok(hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
7917 
7918         test_elem_id((IUnknown*)elem, "in");
7919         test_elem_put_id((IUnknown*)elem, "newin");
7920         test_input_get_disabled(input, VARIANT_FALSE);
7921         test_input_set_disabled(input, VARIANT_TRUE);
7922         test_input_set_disabled(input, VARIANT_FALSE);
7923         test_elem3_set_disabled((IUnknown*)input, VARIANT_TRUE);
7924         test_input_get_disabled(input, VARIANT_TRUE);
7925         test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE);
7926         test_input_get_disabled(input, VARIANT_FALSE);
7927         test_elem_client_size((IUnknown*)elem);
7928         test_input_type(input, "text");
7929         test_elem_istextedit(elem, VARIANT_TRUE);
7930 
7931         test_node_get_value_str((IUnknown*)elem, NULL);
7932         test_node_put_value_str((IUnknown*)elem, "test");
7933         test_node_get_value_str((IUnknown*)elem, NULL);
7934         test_input_value((IUnknown*)elem, NULL);
7935         test_input_defaultValue((IUnknown*)elem, NULL);
7936         test_input_put_value((IUnknown*)elem, "test");
7937         test_input_defaultValue((IUnknown*)elem, NULL);
7938         test_elem_class((IUnknown*)elem, "testclass");
7939         test_elem_tabindex((IUnknown*)elem, 2);
7940         test_elem_set_tabindex((IUnknown*)elem, 3);
7941         test_elem_title((IUnknown*)elem, "test title");
7942 
7943         test_input_get_defaultchecked(input, VARIANT_FALSE);
7944         test_input_set_defaultchecked(input, VARIANT_TRUE);
7945         test_input_set_defaultchecked(input, VARIANT_FALSE);
7946 
7947         test_input_get_checked(input, VARIANT_FALSE);
7948         test_input_set_checked(input, VARIANT_TRUE);
7949         test_input_set_checked(input, VARIANT_FALSE);
7950 
7951         test_input_maxlength(input, 0x7fffffff);
7952         test_input_set_maxlength(input, 30);
7953 
7954         test_input_name(input, NULL);
7955         test_input_set_name(input, "test");
7956 
7957         test_input_src(input, NULL);
7958         test_input_set_src(input, "about:blank");
7959 
7960         test_input_set_size(input, 15, S_OK);
7961         test_input_get_size(input, 15);
7962         test_input_set_size(input, -100, CTL_E_INVALIDPROPERTYVALUE);
7963         test_input_get_size(input, 15);
7964         test_input_set_size(input, 0, CTL_E_INVALIDPROPERTYVALUE);
7965         test_input_get_size(input, 15);
7966 
7967         test_input_readOnly(input, VARIANT_TRUE);
7968         test_input_readOnly(input, VARIANT_FALSE);
7969 
7970         IHTMLInputElement_Release(input);
7971         IHTMLElement_Release(elem);
7972     }
7973 
7974     elem = get_elem_by_id(doc, "imgid", TRUE);
7975     if(elem) {
7976         test_img_align((IUnknown*)elem, "left");
7977         test_img_name((IUnknown*)elem, "WineImg");
7978         test_img_src((IUnknown*)elem, "", NULL);
7979         test_img_set_src((IUnknown*)elem, "about:blank");
7980         test_img_src((IUnknown*)elem, "about:blank", NULL);
7981         test_img_alt((IUnknown*)elem, NULL);
7982         test_img_set_alt((IUnknown*)elem, "alt test");
7983         test_img_name((IUnknown*)elem, "WineImg");
7984         test_img_complete(elem, VARIANT_FALSE);
7985         test_img_isMap((IUnknown*)elem, VARIANT_TRUE);
7986         test_img_isMap((IUnknown*)elem, VARIANT_FALSE);
7987         IHTMLElement_Release(elem);
7988     }
7989 
7990     elem = get_elem_by_id(doc, "attr", TRUE);
7991     if(elem) {
7992         test_dynamic_properties(elem);
7993         test_attr_collection(elem);
7994         test_contenteditable((IUnknown*)elem);
7995         IHTMLElement_Release(elem);
7996     }
7997 
7998     elem = get_elem_by_id(doc, "styleid", TRUE);
7999     if(elem) {
8000         test_style_media((IUnknown*)elem, NULL);
8001         test_style_put_media((IUnknown*)elem, "screen");
8002         test_style_type((IUnknown*)elem, NULL);
8003         test_style_put_type((IUnknown*)elem, "text/css");
8004         IHTMLElement_Release(elem);
8005     }
8006 
8007     elem = get_doc_elem_by_id(doc, "tbl");
8008     ok(elem != NULL, "elem == NULL\n");
8009     if(elem) {
8010         test_table_elem(elem);
8011         IHTMLElement_Release(elem);
8012     }
8013 
8014     elem = get_doc_elem_by_id(doc, "labelid");
8015     ok(elem != NULL, "elem == NULL\n");
8016     if(elem) {
8017         test_label_elem(elem);
8018         IHTMLElement_Release(elem);
8019     }
8020 
8021     elem = get_doc_elem_by_id(doc, "td2");
8022     ok(elem != NULL, "elem == NULL\n");
8023     if(elem) {
8024         test_td_elem(elem);
8025         IHTMLElement_Release(elem);
8026     }
8027 
8028     elem = get_doc_elem_by_id(doc, "row2");
8029     ok(elem != NULL, "elem == NULL\n");
8030     if(elem) {
8031         test_tr_elem(elem);
8032         IHTMLElement_Release(elem);
8033     }
8034 
8035     elem = get_doc_elem_by_id(doc, "ifr");
8036     ok(elem != NULL, "elem == NULL\n");
8037     if(elem) {
8038         test_iframe_elem(elem);
8039         IHTMLElement_Release(elem);
8040     }
8041 
8042     elem = get_doc_elem_by_id(doc, "btnid");
8043     ok(elem != NULL, "elem == NULL\n");
8044     if(elem) {
8045         test_button_elem(elem);
8046         test_button_get_disabled(elem, VARIANT_FALSE);
8047         test_button_set_disabled(elem, VARIANT_TRUE);
8048         test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
8049         test_button_get_disabled(elem, VARIANT_FALSE);
8050         IHTMLElement_Release(elem);
8051     }
8052 
8053     elem = get_doc_elem_by_id(doc, "objid");
8054     ok(elem != NULL, "elem == NULL\n");
8055     if(elem) {
8056         test_object_vspace((IUnknown*)elem, 100);
8057         test_object_name(elem, "objname");
8058         set_object_name(elem, "test");
8059         set_object_name(elem, NULL);
8060         IHTMLElement_Release(elem);
8061     }
8062 
8063     elem = get_elem_by_id(doc, "a", TRUE);
8064     if(elem) {
8065         test_anchor_href((IUnknown*)elem, "http://test/");
8066 
8067         /* Change the href */
8068         test_anchor_put_href((IUnknown*)elem, "http://test1/");
8069         test_anchor_href((IUnknown*)elem, "http://test1/");
8070         test_anchor_hostname((IUnknown*)elem, "test1");
8071 
8072         /* Restore the href */
8073         test_anchor_put_href((IUnknown*)elem, "http://test/");
8074         test_anchor_href((IUnknown*)elem, "http://test/");
8075         test_anchor_hostname((IUnknown*)elem, "test");
8076         test_anchor_hash(elem, NULL);
8077 
8078         /* target */
8079         test_anchor_get_target((IUnknown*)elem, NULL);
8080 
8081         test_anchor_rel((IUnknown*)elem, NULL);
8082         test_anchor_put_rel((IUnknown*)elem, "Next");
8083         test_anchor_rel((IUnknown*)elem, "Next");
8084 
8085         /* Change the target */
8086         test_anchor_put_target((IUnknown*)elem, "wine");
8087         test_anchor_get_target((IUnknown*)elem, "wine");
8088 
8089         /* Restore the target */
8090         test_anchor_put_target((IUnknown*)elem, NULL);
8091         test_anchor_get_target((IUnknown*)elem, NULL);
8092 
8093         test_anchor_name((IUnknown*)elem, "x");
8094         test_anchor_put_name((IUnknown*)elem, "anchor name");
8095         test_anchor_put_name((IUnknown*)elem, NULL);
8096         test_anchor_put_name((IUnknown*)elem, "x");
8097 
8098         test_anchor_put_href((IUnknown*)elem, "http://test/?how#hash");
8099         test_anchor_hash(elem, "#hash");
8100         test_anchor_search((IUnknown*)elem, "?how", FALSE);
8101 
8102         test_anchor_put_search((IUnknown*)elem, "?word=press");
8103         test_anchor_search((IUnknown*)elem, "?word=press", FALSE);
8104         test_anchor_put_search((IUnknown*)elem, "?????word???press");
8105         test_anchor_search((IUnknown*)elem, "?????word???press", FALSE);
8106 
8107         test_anchor_put_search((IUnknown*)elem, "?q=%E4%BD%A0%E5%A5%BD"); /* encoded cjk characters */
8108         test_anchor_search((IUnknown*)elem, "?q=%E4%BD%A0%E5%A5%BD", FALSE);
8109 
8110         test_anchor_put_search((IUnknown*)elem, "?how?old=are");
8111         test_anchor_search((IUnknown*)elem, "?how?old=are", FALSE);
8112 
8113         /* due to incorrect behavior of ie6, search string without leading "?" is interpreted
8114         as part of the pathname, and cannot be accessed by get_search. */
8115         test_anchor_put_search((IUnknown*)elem, "word=abc");
8116         test_anchor_search((IUnknown*)elem, "?word=abc", TRUE);
8117 
8118         IHTMLElement_Release(elem);
8119     }
8120 
8121     elem = get_doc_elem_by_id(doc, "metaid");
8122     if(elem) {
8123         test_meta_name((IUnknown*)elem, "meta name");
8124         test_meta_content((IUnknown*)elem, "text/html; charset=utf-8");
8125         test_meta_httpequiv((IUnknown*)elem, "Content-Type");
8126         test_meta_charset((IUnknown*)elem, NULL);
8127         set_meta_charset((IUnknown*)elem, "utf-8");
8128         IHTMLElement_Release(elem);
8129     }
8130 
8131     elem = doc_get_body(doc);
8132 
8133     node = get_first_child((IUnknown*)elem);
8134     ok(node != NULL, "node == NULL\n");
8135     if(node) {
8136         test_ifaces((IUnknown*)node, text_iids);
8137         test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
8138 
8139         node2 = get_first_child((IUnknown*)node);
8140         ok(!node2, "node2 != NULL\n");
8141 
8142         type = get_node_type((IUnknown*)node);
8143         ok(type == 3, "type=%d\n", type);
8144 
8145         test_node_get_value_str((IUnknown*)node, "text test");
8146         test_node_put_value_str((IUnknown*)elem, "test text");
8147         test_node_get_value_str((IUnknown*)node, "text test");
8148 
8149         hres = IHTMLDOMNode_get_attributes(node, &disp);
8150         ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
8151         ok(!disp, "disp != NULL\n");
8152 
8153         IHTMLDOMNode_Release(node);
8154     }
8155 
8156     child_col = get_child_nodes((IUnknown*)elem);
8157     ok(child_col != NULL, "child_coll == NULL\n");
8158     if(child_col) {
8159         IUnknown *enum_unk;
8160         LONG length = 0;
8161 
8162         test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]");
8163 
8164         hres = IHTMLDOMChildrenCollection_get_length(child_col, &length);
8165         ok(hres == S_OK, "get_length failed: %08x\n", hres);
8166         ok(length, "length=0\n");
8167 
8168         node2 = NULL;
8169         node = get_child_item(child_col, 0);
8170         ok(node != NULL, "node == NULL\n");
8171         if(node) {
8172             IHTMLDOMNode *prev;
8173 
8174             type = get_node_type((IUnknown*)node);
8175             ok(type == 3, "type=%d\n", type);
8176             node2 = node_get_next((IUnknown*)node);
8177 
8178             prev = node_get_prev((IUnknown*)node2);
8179             ok(iface_cmp((IUnknown*)node, (IUnknown*)prev), "node != prev\n");
8180             IHTMLDOMNode_Release(prev);
8181 
8182             IHTMLDOMNode_Release(node);
8183         }
8184 
8185         node = get_child_item(child_col, 1);
8186         ok(node != NULL, "node == NULL\n");
8187         if(node) {
8188             type = get_node_type((IUnknown*)node);
8189             ok(type == 8, "type=%d\n", type);
8190 
8191             test_elem_id((IUnknown*)node, NULL);
8192             ok(iface_cmp((IUnknown*)node2, (IUnknown*)node), "node2 != node\n");
8193             IHTMLDOMNode_Release(node2);
8194             IHTMLDOMNode_Release(node);
8195         }
8196 
8197         hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL);
8198         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
8199 
8200         hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL);
8201         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
8202 
8203         hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp);
8204         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
8205 
8206         hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp);
8207         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
8208 
8209         test_child_col_disp(child_col);
8210 
8211         hres = IHTMLDOMChildrenCollection_get__newEnum(child_col, &enum_unk);
8212         ok(hres == S_OK, "get__newEnum failed: %08x\n", hres);
8213 
8214         test_enum_children(enum_unk, length);
8215 
8216         IUnknown_Release(enum_unk);
8217 
8218         IHTMLDOMChildrenCollection_Release(child_col);
8219     }
8220 
8221     test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
8222     test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
8223     test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
8224 
8225     IHTMLElement_Release(elem);
8226 
8227     elem = get_doc_elem_by_id(doc, "frm");
8228     ok(elem != NULL, "elem == NULL\n");
8229     if(elem) {
8230         test_form_length((IUnknown*)elem, 0);
8231         test_form_elements((IUnknown*)elem);
8232         IHTMLElement_Release(elem);
8233     }
8234 
8235     test_stylesheets(doc);
8236     test_create_option_elem(doc);
8237     test_create_img_elem(doc);
8238 
8239     elem = get_doc_elem_by_id(doc, "tbl");
8240     ok(elem != NULL, "elem = NULL\n");
8241     test_elem_set_innertext(elem, "inner text");
8242     IHTMLElement_Release(elem);
8243 
8244     test_doc_title(doc, "test");
8245     test_doc_set_title(doc, "test title");
8246     test_doc_title(doc, "test title");
8247 
8248     disp = NULL;
8249     hres = IHTMLDocument2_get_Script(doc, &disp);
8250     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
8251     if(hres == S_OK)
8252     {
8253         IDispatchEx *dispex;
8254         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
8255         ok(hres == S_OK, "IDispatch_QueryInterface failed: %08x\n", hres);
8256         if(hres == S_OK)
8257         {
8258             DISPID pid = -1;
8259             BSTR str = a2bstr("Testing");
8260             hres = IDispatchEx_GetDispID(dispex, str, 1, &pid);
8261             ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
8262             ok(pid != -1, "pid == -1\n");
8263             SysFreeString(str);
8264             IDispatchEx_Release(dispex);
8265         }
8266     }
8267     IDispatch_Release(disp);
8268 
8269     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
8270     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
8271 
8272     str = a2bstr("Img");
8273     hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col);
8274     ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres);
8275     SysFreeString(str);
8276     if(hres == S_OK)
8277     {
8278         static const elem_type_t img_types[] = { ET_IMG };
8279 
8280         test_elem_collection((IUnknown*)col, img_types, sizeof(img_types)/sizeof(img_types[0]));
8281         IHTMLElementCollection_Release(col);
8282     }
8283 
8284     elem = get_doc_elem_by_id(doc, "y");
8285     test_elem_set_innerhtml((IUnknown*)elem, "inner html");
8286     test_elem_innerhtml((IUnknown*)elem, "inner html");
8287     test_elem_set_innerhtml((IUnknown*)elem, "");
8288     test_elem_innerhtml((IUnknown*)elem, NULL);
8289     node = node_get_next((IUnknown*)elem);
8290     ok(!node, "node = %p\n", node);
8291 
8292     elem2 = get_doc_elem_by_id(doc, "x");
8293     test_elem_tag((IUnknown*)elem2, "A");
8294     node = node_get_next((IUnknown*)elem2);
8295     IHTMLDOMNode_Release(node);
8296     IHTMLElement_Release(elem2);
8297     IHTMLElement_Release(elem);
8298 
8299     hres = IHTMLDocument3_recalc(doc3, VARIANT_TRUE);
8300     ok(hres == S_OK, "recalc failed: %08x\n", hres);
8301 
8302     IHTMLDocument3_Release(doc3);
8303 
8304     elem = get_elem_by_id(doc, "s", TRUE);
8305     if(elem) {
8306         static const elem_type_t select_types[] = { ET_OPTION, ET_OPTION, ET_OPTION };
8307 
8308         test_select_put_length((IUnknown*)elem, 3);
8309         test_elem_all((IUnknown*)elem, select_types, sizeof(select_types)/sizeof(*select_types));
8310         test_select_put_length((IUnknown*)elem, 1);
8311         test_elem_all((IUnknown*)elem, select_types, 1);
8312         IHTMLElement_Release(elem);
8313     }
8314 
8315     window = get_doc_window(doc);
8316     test_window_name(window, NULL);
8317     set_window_name(window, "test name");
8318     test_window_length(window, 1);
8319     IHTMLWindow2_Release(window);
8320 }
8321 
test_attr(IHTMLElement * elem)8322 static void test_attr(IHTMLElement *elem)
8323 {
8324     IHTMLDOMAttribute *attr, *attr2;
8325     VARIANT v;
8326 
8327     get_elem_attr_node((IUnknown*)elem, "noattr", FALSE);
8328 
8329     attr = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
8330 
8331     test_disp((IUnknown*)attr, &DIID_DispHTMLDOMAttribute, "[object]");
8332     test_ifaces((IUnknown*)attr, attr_iids);
8333     test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
8334     test_attr_specified(attr, VARIANT_TRUE);
8335 
8336     attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
8337     ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");
8338     IHTMLDOMAttribute_Release(attr2);
8339 
8340     get_attr_node_value(attr, &v, VT_BSTR);
8341     ok(!strcmp_wa(V_BSTR(&v), "divid"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
8342     VariantClear(&v);
8343 
8344     V_VT(&v) = VT_BSTR;
8345     V_BSTR(&v) = a2bstr("divid2");
8346     put_attr_node_value(attr, v);
8347 
8348     get_attr_node_value(attr, &v, VT_BSTR);
8349     ok(!strcmp_wa(V_BSTR(&v), "divid2"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
8350     VariantClear(&v);
8351 
8352     IHTMLDOMAttribute_Release(attr);
8353 
8354     attr = get_elem_attr_node((IUnknown*)elem, "emptyattr", TRUE);
8355     get_attr_node_value(attr, &v, VT_BSTR);
8356     ok(!V_BSTR(&v), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
8357     VariantClear(&v);
8358 
8359     V_VT(&v) = VT_BSTR;
8360     V_BSTR(&v) = a2bstr("newvalue");
8361     put_attr_node_value(attr, v);
8362     VariantClear(&v);
8363 
8364     attr = get_elem_attr_node((IUnknown*)elem, "emptyattr", TRUE);
8365     get_attr_node_value(attr, &v, VT_BSTR);
8366     ok(!strcmp_wa(V_BSTR(&v), "newvalue"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
8367     VariantClear(&v);
8368 
8369     test_attr_specified(attr, VARIANT_TRUE);
8370     IHTMLDOMAttribute_Release(attr);
8371 
8372     V_VT(&v) = VT_I4;
8373     V_I4(&v) = 100;
8374     set_dispex_value((IUnknown*)elem, "dispprop", &v);
8375     attr = get_elem_attr_node((IUnknown*)elem, "dispprop", TRUE);
8376     get_attr_node_value(attr, &v, VT_I4);
8377     ok(V_I4(&v) == 100, "V_I4(v) = %d\n", V_I4(&v));
8378     test_attr_specified(attr, VARIANT_TRUE);
8379 
8380     V_VT(&v) = VT_I4;
8381     V_I4(&v) = 150;
8382     put_attr_node_value(attr, v);
8383 
8384     get_attr_node_value(attr, &v, VT_I4);
8385     ok(V_I4(&v) == 150, "V_I4(v) = %d\n", V_I4(&v));
8386 
8387     IHTMLDOMAttribute_Release(attr);
8388 
8389     attr = get_elem_attr_node((IUnknown*)elem, "tabIndex", TRUE);
8390     test_attr_specified(attr, VARIANT_FALSE);
8391     test_attr_expando(attr, VARIANT_FALSE);
8392     IHTMLDOMAttribute_Release(attr);
8393 }
8394 
test_blocked(IHTMLDocument2 * doc,IHTMLElement * outer_elem)8395 static void test_blocked(IHTMLDocument2 *doc, IHTMLElement *outer_elem)
8396 {
8397     IHTMLElement *elem;
8398 
8399     test_elem_set_innerhtml((IUnknown*)outer_elem,
8400             "<img id=\"imgid\" src=\"BLOCKED::http://www.winehq.org/img.png\" />");
8401     elem = get_elem_by_id(doc, "imgid", TRUE);
8402     if(elem) {
8403         test_img_src((IUnknown*)elem, "BLOCKED::", "blocked::http://www.winehq.org/img.png");
8404         IHTMLElement_Release(elem);
8405     }
8406 
8407     test_elem_set_innerhtml((IUnknown*)outer_elem,
8408             "<img id=\"imgid\" src=\"BLOCKE::http://www.winehq.org/img.png\" />");
8409     elem = get_elem_by_id(doc, "imgid", TRUE);
8410     if(elem) {
8411         test_img_src((IUnknown*)elem, "blocke::http://www.winehq.org/img.png", NULL);
8412         test_img_set_src((IUnknown*)elem, "BLOCKED:http://www.winehq.org/img.png");
8413         test_img_src((IUnknown*)elem, "blocked:http://www.winehq.org/img.png", NULL);
8414         test_img_set_src((IUnknown*)elem, "blocked::http://www.winehq.org/img.png");
8415         test_img_src((IUnknown*)elem, "BLOCKED::", "blocked::http://www.winehq.org/img.png");
8416         IHTMLElement_Release(elem);
8417     }
8418 }
8419 
8420 #define doc_get_elems_by_name(a,b) _doc_get_elems_by_name(__LINE__,a,b)
_doc_get_elems_by_name(unsigned line,IHTMLDocument2 * doc,const char * name)8421 static IHTMLElementCollection *_doc_get_elems_by_name(unsigned line, IHTMLDocument2 *doc, const char *name)
8422 {
8423     IHTMLDocument3 *doc3 = _get_doc3_iface(line, doc);
8424     IHTMLElementCollection *col;
8425     BSTR str = a2bstr(name);
8426     HRESULT hres;
8427 
8428     hres = IHTMLDocument3_getElementsByName(doc3, str, &col);
8429     ok_(__FILE__,line)(hres == S_OK, "getElementsByName failed: %08x\n", hres);
8430     ok_(__FILE__,line)(col != NULL, "col = NULL\n");
8431 
8432     IHTMLDocument3_Release(doc3);
8433     SysFreeString(str);
8434     return col;
8435 }
8436 
test_elem_names(IHTMLDocument2 * doc)8437 static void test_elem_names(IHTMLDocument2 *doc)
8438 {
8439     IHTMLElementCollection *col;
8440     IHTMLElement *body;
8441     LONG len;
8442     HRESULT hres;
8443 
8444     static const elem_type_t test1_types[] = {ET_INPUT, ET_A, ET_DIV};
8445 
8446     body = doc_get_body(doc);
8447 
8448     test_elem_set_innerhtml((IUnknown*)body,
8449             "<input name=\"test\"><a name=\"test\"></a><a name=\"xxx\"></a><div id=\"test\"></div>");
8450     col = doc_get_elems_by_name(doc, "test");
8451     test_elem_collection((IUnknown*)col, test1_types, sizeof(test1_types)/sizeof(*test1_types));
8452     IHTMLElementCollection_Release(col);
8453 
8454     col = doc_get_elems_by_name(doc, "yyy");
8455     test_elem_collection((IUnknown*)col, NULL, 0);
8456     IHTMLElementCollection_Release(col);
8457 
8458     /* case insensivity test */
8459     col = doc_get_elems_by_name(doc, "Xxx");
8460     hres = IHTMLElementCollection_get_length(col, &len);
8461     ok(hres == S_OK, "get_length failed: %08x\n", hres);
8462     todo_wine ok(len == 1, "len = %d\n", len);
8463     IHTMLElementCollection_Release(col);
8464 
8465     IHTMLElement_Release(body);
8466 }
8467 
test_elems2(IHTMLDocument2 * doc)8468 static void test_elems2(IHTMLDocument2 *doc)
8469 {
8470     IHTMLElement *elem, *elem2, *div;
8471 
8472     static const elem_type_t outer_types[] = {
8473         ET_BR,
8474         ET_A
8475     };
8476 
8477     div = get_doc_elem_by_id(doc, "divid");
8478 
8479     elem = get_elem_by_id(doc, "linkid", TRUE);
8480     if(elem) {
8481         test_link_disabled(elem, VARIANT_FALSE);
8482         test_link_rel(elem, "stylesheet");
8483         test_link_rev(elem, NULL);
8484         test_link_type(elem, "text/css");
8485         test_link_href(elem, "about:blank");
8486         test_link_media(elem, "all");
8487         link_put_disabled(elem, VARIANT_TRUE);
8488         link_put_rel(elem, "prev");
8489         link_put_rev(elem, "next");
8490         link_put_type(elem, "text/plain");
8491         link_put_href(elem, "about:prev");
8492         IHTMLElement_Release(elem);
8493     }
8494 
8495     test_elem_set_innerhtml((IUnknown*)div, "<div id=\"innerid\"></div>");
8496     elem2 = get_doc_elem_by_id(doc, "innerid");
8497     ok(elem2 != NULL, "elem2 == NULL\n");
8498     test_elem_set_outerhtml((IUnknown*)elem2, "<br><a href=\"about:blank\" id=\"aid\">a</a>");
8499     test_elem_all((IUnknown*)div, outer_types, sizeof(outer_types)/sizeof(*outer_types));
8500     IHTMLElement_Release(elem2);
8501 
8502     elem2 = get_doc_elem_by_id(doc, "aid");
8503     ok(elem2 != NULL, "elem2 == NULL\n");
8504     test_elem_set_outerhtml((IUnknown*)elem2, "");
8505     test_elem_all((IUnknown*)div, outer_types, 1);
8506     IHTMLElement_Release(elem2);
8507 
8508     test_elem_set_innerhtml((IUnknown*)div, "<textarea id=\"ta\"></textarea>");
8509     elem = get_elem_by_id(doc, "ta", TRUE);
8510     if(elem) {
8511         IHTMLFormElement *form;
8512 
8513         test_textarea_value((IUnknown*)elem, NULL);
8514         test_textarea_put_value((IUnknown*)elem, "test");
8515         test_textarea_defaultvalue((IUnknown*)elem, NULL);
8516         test_textarea_put_defaultvalue((IUnknown*)elem, "defval text");
8517         test_textarea_put_value((IUnknown*)elem, "test");
8518         test_textarea_readonly((IUnknown*)elem, VARIANT_FALSE);
8519         test_textarea_put_readonly((IUnknown*)elem, VARIANT_TRUE);
8520         test_textarea_put_readonly((IUnknown*)elem, VARIANT_FALSE);
8521         test_textarea_type((IUnknown*)elem);
8522 
8523         form = get_textarea_form((IUnknown*)elem);
8524         ok(!form, "form = %p\n", form);
8525 
8526         test_elem_istextedit(elem, VARIANT_TRUE);
8527 
8528         IHTMLElement_Release(elem);
8529     }
8530 
8531     test_elem_set_innerhtml((IUnknown*)div, "<textarea id=\"ta\">default text</textarea>");
8532     elem = get_elem_by_id(doc, "ta", TRUE);
8533     if(elem) {
8534         test_textarea_defaultvalue((IUnknown*)elem, "default text");
8535         IHTMLElement_Release(elem);
8536     }
8537 
8538     test_elem_set_innerhtml((IUnknown*)div, "<form id=\"fid\"><textarea id=\"ta\"></textarea></form>");
8539     elem = get_elem_by_id(doc, "ta", TRUE);
8540     if(elem) {
8541         IHTMLFormElement *form;
8542 
8543         elem2 = get_elem_by_id(doc, "fid", TRUE);
8544         ok(elem2 != NULL, "elem2 == NULL\n");
8545 
8546         form = get_textarea_form((IUnknown*)elem);
8547         ok(form != NULL, "form = NULL\n");
8548         ok(iface_cmp((IUnknown*)form, (IUnknown*)elem2), "form != elem2\n");
8549 
8550         IHTMLFormElement_Release(form);
8551         IHTMLElement_Release(elem2);
8552         IHTMLElement_Release(elem);
8553     }
8554 
8555     test_elem_set_innerhtml((IUnknown*)div,
8556             "<input value=\"val\" id =\"inputid\"  />");
8557     elem = get_elem_by_id(doc, "inputid", TRUE);
8558     if(elem) {
8559         test_input_defaultValue((IUnknown*)elem, "val");
8560         test_input_put_value((IUnknown*)elem, "test");
8561         test_input_put_defaultValue((IUnknown*)elem, "new val");
8562         test_input_value((IUnknown*)elem, "test");
8563         IHTMLElement_Release(elem);
8564     }
8565 
8566     test_elem_set_innerhtml((IUnknown*)div, "");
8567     test_insert_adjacent_elems(doc, div);
8568 
8569     test_elem_set_innerhtml((IUnknown*)div,
8570             "<form id=\"form\"><input type=\"button\" /><div><input type=\"text\" id=\"inputid\"/></div></textarea>");
8571     elem = get_elem_by_id(doc, "form", TRUE);
8572     if(elem) {
8573         test_form_length((IUnknown*)elem, 2);
8574         test_form_item(elem);
8575         test_form_action((IUnknown*)elem, NULL);
8576         test_form_put_action((IUnknown*)elem, "about:blank");
8577         test_form_method((IUnknown*)elem, "get");
8578         test_form_put_method((IUnknown*)elem, S_OK, "post");
8579         test_form_put_method((IUnknown*)elem, E_INVALIDARG, "put");
8580         test_form_method((IUnknown*)elem, "post");
8581         test_form_name((IUnknown*)elem, NULL);
8582         test_form_put_name((IUnknown*)elem, "Name");
8583         test_form_encoding((IUnknown*)elem, "application/x-www-form-urlencoded");
8584         test_form_put_encoding((IUnknown*)elem, S_OK, "text/plain");
8585         test_form_put_encoding((IUnknown*)elem, S_OK, "multipart/form-data");
8586         test_form_put_encoding((IUnknown*)elem, E_INVALIDARG, "image/png");
8587         test_form_encoding((IUnknown*)elem, "multipart/form-data");
8588         test_form_elements((IUnknown*)elem);
8589         test_form_reset((IUnknown*)elem);
8590         test_form_target((IUnknown*)elem);
8591         IHTMLElement_Release(elem);
8592 
8593         elem = get_elem_by_id(doc, "inputid", TRUE);
8594         test_input_get_form((IUnknown*)elem, "form");
8595         IHTMLElement_Release(elem);
8596     }
8597 
8598     test_elem_set_innerhtml((IUnknown*)div,
8599             "<form id=\"form\" name=\"form_name\"><select id=\"sform\"><option id=\"oform\"></option></select></form>");
8600     elem = get_elem_by_id(doc, "sform", TRUE);
8601     elem2 = get_elem_by_id(doc, "form", TRUE);
8602     if(elem && elem2) {
8603         test_select_form((IUnknown*)elem, (IUnknown*)elem2);
8604         IHTMLElement_Release(elem);
8605 
8606         elem = get_elem_by_id(doc, "oform", TRUE);
8607         if(elem) {
8608             test_option_form((IUnknown*)elem, (IUnknown*)elem2);
8609             IHTMLElement_Release(elem);
8610         }
8611         IHTMLElement_Release(elem2);
8612     }
8613 
8614     test_attr(div);
8615     test_blocked(doc, div);
8616     test_elem_names(doc);
8617 
8618     IHTMLElement_Release(div);
8619 }
8620 
test_create_elems(IHTMLDocument2 * doc)8621 static void test_create_elems(IHTMLDocument2 *doc)
8622 {
8623     IHTMLElement *elem, *body, *elem2;
8624     IHTMLDOMNode *node, *node2, *node3, *comment;
8625     IHTMLDOMAttribute *attr;
8626     IHTMLDocument5 *doc5;
8627     IDispatch *disp;
8628     VARIANT var;
8629     LONG type;
8630     HRESULT hres;
8631     BSTR str;
8632 
8633     static const elem_type_t types1[] = { ET_TESTG };
8634 
8635     elem = test_create_elem(doc, "TEST");
8636     test_elem_tag((IUnknown*)elem, "TEST");
8637     type = get_node_type((IUnknown*)elem);
8638     ok(type == 1, "type=%d\n", type);
8639     test_ifaces((IUnknown*)elem, elem_iids);
8640     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
8641     test_elem_source_index(elem, -1);
8642 
8643     body = doc_get_body(doc);
8644     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
8645 
8646     node = test_node_append_child((IUnknown*)body, (IUnknown*)elem);
8647     test_node_has_child((IUnknown*)body, VARIANT_TRUE);
8648     elem2 = get_elem_iface((IUnknown*)node);
8649     IHTMLElement_Release(elem2);
8650 
8651     hres = IHTMLElement_get_all(body, &disp);
8652     ok(hres == S_OK, "get_all failed: %08x\n", hres);
8653     test_elem_collection((IUnknown*)disp, types1, sizeof(types1)/sizeof(types1[0]));
8654     IDispatch_Release(disp);
8655 
8656     test_node_remove_child((IUnknown*)body, node);
8657 
8658     hres = IHTMLElement_get_all(body, &disp);
8659     ok(hres == S_OK, "get_all failed: %08x\n", hres);
8660     test_elem_collection((IUnknown*)disp, NULL, 0);
8661     IDispatch_Release(disp);
8662     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
8663 
8664     IHTMLElement_Release(elem);
8665     IHTMLDOMNode_Release(node);
8666 
8667     node = test_create_text(doc, "abc");
8668     test_ifaces((IUnknown*)node, text_iids);
8669     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
8670     test_text_length((IUnknown*)node, 3);
8671     test_text_data((IUnknown*)node, "abc");
8672     set_text_data((IUnknown*)node, "test");
8673     test_text_data((IUnknown*)node, "test");
8674     text_append_data((IUnknown*)node, " append");
8675     test_text_data((IUnknown*)node, "test append");
8676     text_append_data((IUnknown*)node, NULL);
8677     test_text_data((IUnknown*)node, "test append");
8678     set_text_data((IUnknown*)node, "test");
8679 
8680     V_VT(&var) = VT_NULL;
8681     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
8682     IHTMLDOMNode_Release(node);
8683 
8684     node = test_create_text(doc, "insert ");
8685 
8686     V_VT(&var) = VT_DISPATCH;
8687     V_DISPATCH(&var) = (IDispatch*)node2;
8688     node3 = test_node_insertbefore((IUnknown*)body, node, &var);
8689     IHTMLDOMNode_Release(node);
8690     IHTMLDOMNode_Release(node2);
8691     IHTMLDOMNode_Release(node3);
8692 
8693     test_elem_innertext(body, "insert test");
8694     test_elem_innerhtml((IUnknown*)body, "insert test");
8695 
8696     node = test_create_text(doc, " Test");
8697     V_VT(&var) = VT_DISPATCH;
8698     V_DISPATCH(&var) = NULL;
8699     test_node_insertbefore((IUnknown*)body, node, &var);
8700     test_elem_innertext(body, "insert test Test");
8701     IHTMLDOMNode_Release(node);
8702 
8703     doc5 = get_htmldoc5_iface((IUnknown*)doc);
8704     if(doc5) {
8705         str = a2bstr("testing");
8706         hres = IHTMLDocument5_createComment(doc5, str, &comment);
8707         SysFreeString(str);
8708         ok(hres == S_OK, "createComment failed: %08x\n", hres);
8709         if(hres == S_OK)
8710         {
8711             type = get_node_type((IUnknown*)comment);
8712             ok(type == 8, "type=%d, expected 8\n", type);
8713 
8714             test_node_get_value_str((IUnknown*)comment, "testing");
8715             test_elem_title((IUnknown*)comment, NULL);
8716             test_elem_set_title((IUnknown*)comment, "comment title");
8717             test_elem_title((IUnknown*)comment, "comment title");
8718             test_comment_text((IUnknown*)comment, "<!--testing-->");
8719             test_elem_outerhtml((IUnknown*)comment, "<!--testing-->");
8720             test_comment_attrs((IUnknown*)comment);
8721 
8722             IHTMLDOMNode_Release(comment);
8723         }
8724 
8725         str = a2bstr("Test");
8726         hres = IHTMLDocument5_createAttribute(doc5, str, &attr);
8727         ok(hres == S_OK, "createAttribute dailed: %08x\n", hres);
8728         SysFreeString(str);
8729         if(SUCCEEDED(hres)) {
8730             test_disp((IUnknown*)attr, &DIID_DispHTMLDOMAttribute, "[object]");
8731             test_ifaces((IUnknown*)attr, attr_iids);
8732             test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
8733 
8734             test_attr_node_name(attr, "Test");
8735 
8736             IHTMLDOMAttribute_Release(attr);
8737         }
8738 
8739         IHTMLDocument5_Release(doc5);
8740     }
8741 
8742     IHTMLElement_Release(body);
8743 }
8744 
test_replacechild_elems(IHTMLDocument2 * doc)8745 static void test_replacechild_elems(IHTMLDocument2 *doc)
8746 {
8747     IHTMLElement *body;
8748     IHTMLDOMNode *node, *node2, *node3;
8749     IHTMLDOMNode *nodeBody, *nodeNew;
8750     HRESULT hres;
8751     VARIANT var;
8752 
8753     body = doc_get_body(doc);
8754 
8755     node = test_create_text(doc, "insert");
8756 
8757     V_VT(&var) = VT_NULL;
8758     V_DISPATCH(&var) = NULL;
8759     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
8760     IHTMLDOMNode_Release(node);
8761 
8762     test_elem_innertext(body, "insert");
8763 
8764     node3 = test_create_text(doc, "replaced");
8765 
8766     nodeBody = _get_node_iface(__LINE__, (IUnknown *)body);
8767 
8768     hres = IHTMLDOMNode_replaceChild(nodeBody, node3, node2, &nodeNew);
8769     ok(hres == S_OK, "Expected S_OK, got 0x%08x\n", hres);
8770 
8771     test_elem_innertext(body, "replaced");
8772 
8773     IHTMLDOMNode_Release(node2);
8774     IHTMLDOMNode_Release(node3);
8775     IHTMLDOMNode_Release(nodeBody);
8776 
8777     IHTMLElement_Release(body);
8778 }
8779 
test_noscript(IHTMLDocument2 * doc)8780 static void test_noscript(IHTMLDocument2 *doc)
8781 {
8782     IHTMLElementCollection *col;
8783     IHTMLElement *body;
8784     HRESULT hres;
8785 
8786     static const elem_type_t all_types[] = {
8787         ET_HTML,
8788         ET_HEAD,
8789         ET_TITLE,
8790         ET_NOSCRIPT,
8791         ET_BODY,
8792         ET_NOSCRIPT
8793     };
8794 
8795     static const elem_type_t body_all_types[] = {
8796         ET_DIV,
8797         ET_NOSCRIPT
8798     };
8799 
8800     hres = IHTMLDocument2_get_all(doc, &col);
8801     ok(hres == S_OK, "get_all failed: %08x\n", hres);
8802     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
8803     IHTMLElementCollection_Release(col);
8804 
8805     body = doc_get_body(doc);
8806     test_elem_set_innerhtml((IUnknown*)body, "<div>test</div><noscript><a href=\"about:blank\">A</a></noscript>");
8807     test_elem_all((IUnknown*)body, body_all_types, sizeof(body_all_types)/sizeof(*body_all_types));
8808     IHTMLElement_Release(body);
8809 }
8810 
test_doctype(IHTMLDocument2 * doc)8811 static void test_doctype(IHTMLDocument2 *doc)
8812 {
8813     IHTMLDocument2 *doc_node;
8814     IHTMLDOMNode *doctype;
8815     int type;
8816 
8817     doc_node = get_doc_node(doc);
8818     doctype = get_first_child((IUnknown*)doc_node);
8819     IHTMLDocument2_Release(doc_node);
8820 
8821     type = get_node_type((IUnknown*)doctype);
8822     ok(type == 8, "type = %d\n", type);
8823 
8824     test_comment_text((IUnknown*)doctype, "<!DOCTYPE html>");
8825     test_elem_type((IUnknown*)doctype, ET_COMMENT);
8826     IHTMLDOMNode_Release(doctype);
8827 }
8828 
test_null_write(IHTMLDocument2 * doc)8829 static void test_null_write(IHTMLDocument2 *doc)
8830 {
8831     HRESULT hres;
8832 
8833     doc_write(doc, FALSE, NULL);
8834     doc_write(doc, TRUE, NULL);
8835 
8836     hres = IHTMLDocument2_write(doc, NULL);
8837     ok(hres == S_OK,
8838        "Expected IHTMLDocument2::write to return S_OK, got 0x%08x\n", hres);
8839 
8840     hres = IHTMLDocument2_writeln(doc, NULL);
8841     ok(hres == S_OK,
8842        "Expected IHTMLDocument2::writeln to return S_OK, got 0x%08x\n", hres);
8843 }
8844 
test_create_stylesheet(IHTMLDocument2 * doc)8845 static void test_create_stylesheet(IHTMLDocument2 *doc)
8846 {
8847     IHTMLStyleSheet *stylesheet, *stylesheet2;
8848     IHTMLStyleElement *style_elem;
8849     IHTMLElement *doc_elem, *elem;
8850     HRESULT hres;
8851 
8852     static const elem_type_t all_types[] = {
8853         ET_HTML,
8854         ET_HEAD,
8855         ET_TITLE,
8856         ET_BODY,
8857         ET_DIV
8858     };
8859 
8860     static const elem_type_t all_types2[] = {
8861         ET_HTML,
8862         ET_HEAD,
8863         ET_TITLE,
8864         ET_STYLE,
8865         ET_BODY,
8866         ET_DIV
8867     };
8868 
8869     test_doc_all(doc, all_types, sizeof(all_types)/sizeof(*all_types));
8870 
8871     hres = IHTMLDocument2_createStyleSheet(doc, NULL, -1, &stylesheet);
8872     ok(hres == S_OK, "createStyleSheet failed: %08x\n", hres);
8873 
8874     test_doc_all(doc, all_types2, sizeof(all_types2)/sizeof(*all_types2));
8875 
8876     doc_elem = get_doc_elem(doc);
8877 
8878     test_elem_getelembytag((IUnknown*)doc_elem, ET_STYLE, 1, &elem);
8879     IHTMLElement_Release(doc_elem);
8880 
8881     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLStyleElement, (void**)&style_elem);
8882     IHTMLElement_Release(elem);
8883     ok(hres == S_OK, "Could not get IHTMLStyleElement iface: %08x\n", hres);
8884 
8885     stylesheet2 = NULL;
8886     hres = IHTMLStyleElement_get_styleSheet(style_elem, &stylesheet2);
8887     ok(hres == S_OK, "get_styleSheet failed: %08x\n", hres);
8888     ok(stylesheet2 != NULL, "stylesheet2 == NULL\n");
8889     ok(iface_cmp((IUnknown*)stylesheet, (IUnknown*)stylesheet2), "stylesheet != stylesheet2\n");
8890 
8891     IHTMLStyleSheet_Release(stylesheet2);
8892     IHTMLStyleSheet_Release(stylesheet);
8893 
8894     IHTMLStyleElement_Release(style_elem);
8895 }
8896 
test_exec(IUnknown * unk,const GUID * grpid,DWORD cmdid,VARIANT * in,VARIANT * out)8897 static void test_exec(IUnknown *unk, const GUID *grpid, DWORD cmdid, VARIANT *in, VARIANT *out)
8898 {
8899     IOleCommandTarget *cmdtrg;
8900     HRESULT hres;
8901 
8902     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
8903     ok(hres == S_OK, "Could not get IOleCommandTarget interface: %08x\n", hres);
8904 
8905     hres = IOleCommandTarget_Exec(cmdtrg, grpid, cmdid, 0, in, out);
8906     ok(hres == S_OK, "Exec failed: %08x\n", hres);
8907 
8908     IOleCommandTarget_Release(cmdtrg);
8909 }
8910 
test_indent(IHTMLDocument2 * doc)8911 static void test_indent(IHTMLDocument2 *doc)
8912 {
8913     IHTMLElementCollection *col;
8914     IHTMLTxtRange *range;
8915     HRESULT hres;
8916 
8917     static const elem_type_t all_types[] = {
8918         ET_HTML,
8919         ET_HEAD,
8920         ET_TITLE,
8921         ET_BODY,
8922         ET_BR,
8923         ET_A,
8924     };
8925 
8926     static const elem_type_t indent_types[] = {
8927         ET_HTML,
8928         ET_HEAD,
8929         ET_TITLE,
8930         ET_BODY,
8931         ET_BLOCKQUOTE,
8932         ET_P,
8933         ET_BR,
8934         ET_A,
8935     };
8936 
8937     hres = IHTMLDocument2_get_all(doc, &col);
8938     ok(hres == S_OK, "get_all failed: %08x\n", hres);
8939     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
8940     IHTMLElementCollection_Release(col);
8941 
8942     range = test_create_body_range(doc);
8943     test_exec((IUnknown*)range, &CGID_MSHTML, IDM_INDENT, NULL, NULL);
8944     IHTMLTxtRange_Release(range);
8945 
8946     hres = IHTMLDocument2_get_all(doc, &col);
8947     ok(hres == S_OK, "get_all failed: %08x\n", hres);
8948     test_elem_collection((IUnknown*)col, indent_types, sizeof(indent_types)/sizeof(indent_types[0]));
8949     IHTMLElementCollection_Release(col);
8950 }
8951 
test_cond_comment(IHTMLDocument2 * doc)8952 static void test_cond_comment(IHTMLDocument2 *doc)
8953 {
8954     IHTMLElementCollection *col;
8955     HRESULT hres;
8956 
8957     static const elem_type_t all_types[] = {
8958         ET_HTML,
8959         ET_HEAD,
8960         ET_TITLE,
8961         ET_BODY,
8962         ET_BR
8963     };
8964 
8965     hres = IHTMLDocument2_get_all(doc, &col);
8966     ok(hres == S_OK, "get_all failed: %08x\n", hres);
8967     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
8968     IHTMLElementCollection_Release(col);
8969 }
8970 
Unknown_QueryInterface(IUnknown * iface,REFIID riid,void ** ppv)8971 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
8972 {
8973     ok(IsEqualGUID(riid, &IID_IServiceProvider), "riid = %s\n", wine_dbgstr_guid(riid));
8974     return E_NOINTERFACE;
8975 }
8976 
Unknown_AddRef(IUnknown * iface)8977 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
8978 {
8979     return 2;
8980 }
8981 
Unknown_Release(IUnknown * iface)8982 static ULONG WINAPI Unknown_Release(IUnknown *iface)
8983 {
8984     return 1;
8985 }
8986 
8987 static const IUnknownVtbl UnknownVtbl = {
8988     Unknown_QueryInterface,
8989     Unknown_AddRef,
8990     Unknown_Release,
8991 };
8992 static IUnknown obj_ident_test = { &UnknownVtbl };
8993 
test_frame(IDispatch * disp,const char * exp_id)8994 static void test_frame(IDispatch *disp, const char *exp_id)
8995 {
8996     IHTMLWindow2 *frame2, *parent, *top;
8997     IHTMLDocument2 *parent_doc, *top_doc;
8998     IHTMLWindow4 *frame;
8999     IHTMLFrameBase *frame_elem;
9000     IObjectIdentity *obj_ident;
9001     ITravelLogClient *tlc;
9002     HRESULT hres;
9003 
9004     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame);
9005     ok(hres == S_OK, "Could not get IHTMLWindow4 interface: 0x%08x\n", hres);
9006     if(FAILED(hres))
9007         return;
9008 
9009     hres = IHTMLWindow4_get_frameElement(frame, &frame_elem);
9010     ok(hres == S_OK, "IHTMLWindow4_get_frameElement failed: 0x%08x\n", hres);
9011     IHTMLWindow4_Release(frame);
9012     if(FAILED(hres))
9013         return;
9014 
9015     test_elem_type((IUnknown*)frame_elem, ET_FRAME);
9016     test_frame_doc((IUnknown*)frame_elem, FALSE);
9017     test_elem_id((IUnknown*)frame_elem, exp_id);
9018     IHTMLFrameBase_Release(frame_elem);
9019 
9020     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow2, (void**)&frame2);
9021     ok(hres == S_OK, "Could not get IHTMLWindow2 interface: 0x%08x\n", hres);
9022     if(FAILED(hres))
9023         return;
9024 
9025     hres = IHTMLWindow2_get_parent(frame2, &parent);
9026     ok(hres == S_OK, "IHTMLWindow2_get_parent failed: 0x%08x\n", hres);
9027     if(FAILED(hres)){
9028         IHTMLWindow2_Release(frame2);
9029         return;
9030     }
9031 
9032     hres = IHTMLWindow2_QueryInterface(frame2, &IID_IObjectIdentity, (void**)&obj_ident);
9033     ok(hres == S_OK, "Could not get IObjectIdentity interface: %08x\n", hres);
9034     hres = IHTMLWindow2_QueryInterface(frame2, &IID_ITravelLogClient, (void**)&tlc);
9035     if(hres == E_NOINTERFACE) {
9036         win_skip("IID_ITravelLogClient not available\n");
9037         tlc = NULL;
9038     }else {
9039         ok(hres == S_OK, "Could not get ITravelLogClient interface: %08x\n", hres);
9040 
9041         hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)tlc);
9042         ok(hres == S_OK, "IsEqualObject returned: 0x%08x\n", hres);
9043         ITravelLogClient_Release(tlc);
9044     }
9045 
9046     hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)obj_ident);
9047     ok(hres == S_OK, "IsEqualObject returned: 0x%08x\n", hres);
9048     hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)parent);
9049     ok(hres == S_FALSE, "IsEqualObject returned: 0x%08x\n", hres);
9050     hres = IObjectIdentity_IsEqualObject(obj_ident, &obj_ident_test);
9051     ok(hres == E_NOINTERFACE, "IsEqualObject returned: 0x%08x\n", hres);
9052 
9053     IObjectIdentity_Release(obj_ident);
9054 
9055     hres = IHTMLWindow2_get_document(parent, &parent_doc);
9056     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
9057     IHTMLWindow2_Release(parent);
9058     if(FAILED(hres)){
9059         IHTMLWindow2_Release(frame2);
9060         return;
9061     }
9062 
9063     test_doc_title(parent_doc, "frameset test");
9064     IHTMLDocument2_Release(parent_doc);
9065 
9066     /* test get_top */
9067     hres = IHTMLWindow2_get_top(frame2, &top);
9068     ok(hres == S_OK, "IHTMLWindow2_get_top failed: 0x%08x\n", hres);
9069     IHTMLWindow2_Release(frame2);
9070     if(FAILED(hres))
9071         return;
9072 
9073     hres = IHTMLWindow2_get_document(top, &top_doc);
9074     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
9075     IHTMLWindow2_Release(top);
9076     if(FAILED(hres))
9077         return;
9078 
9079     test_doc_title(top_doc, "frameset test");
9080     IHTMLDocument2_Release(top_doc);
9081 }
9082 
test_frames_collection(IHTMLFramesCollection2 * frames,const char * frid)9083 static void test_frames_collection(IHTMLFramesCollection2 *frames, const char *frid)
9084 {
9085     VARIANT index_var, result_var;
9086     LONG length;
9087     HRESULT hres;
9088 
9089     /* test result length */
9090     hres = IHTMLFramesCollection2_get_length(frames, &length);
9091     ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres);
9092     ok(length == 3, "IHTMLFramesCollection2_get_length should have been 3, was: %d\n", length);
9093 
9094     /* test first frame */
9095     V_VT(&index_var) = VT_I4;
9096     V_I4(&index_var) = 0;
9097     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
9098     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
9099     if(SUCCEEDED(hres)) {
9100         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
9101         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
9102     }
9103     VariantClear(&result_var);
9104 
9105     /* test second frame */
9106     V_I4(&index_var) = 1;
9107     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
9108     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
9109     if(SUCCEEDED(hres)) {
9110         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
9111         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
9112     }
9113     VariantClear(&result_var);
9114 
9115     /* fail on next frame */
9116     V_I4(&index_var) = 3;
9117     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
9118     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have"
9119            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
9120     VariantClear(&result_var);
9121 
9122     /* string argument (element id lookup) */
9123     V_VT(&index_var) = VT_BSTR;
9124     V_BSTR(&index_var) = a2bstr(frid);
9125     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
9126     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
9127     if(SUCCEEDED(hres)) {
9128         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
9129         test_frame(V_DISPATCH(&result_var), frid);
9130     }
9131     VariantClear(&result_var);
9132     VariantClear(&index_var);
9133 
9134     /* invalid argument */
9135     V_VT(&index_var) = VT_BOOL;
9136     V_BOOL(&index_var) = VARIANT_TRUE;
9137     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
9138     ok(hres == E_INVALIDARG, "IHTMLFramesCollection2_item should have"
9139            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
9140     VariantClear(&result_var);
9141 }
9142 
test_frameset(IHTMLDocument2 * doc)9143 static void test_frameset(IHTMLDocument2 *doc)
9144 {
9145     IHTMLWindow2 *window;
9146     IHTMLFramesCollection2 *frames;
9147     IHTMLElement *elem;
9148     HRESULT hres;
9149 
9150     window = get_doc_window(doc);
9151 
9152     /* test using IHTMLFramesCollection object */
9153 
9154     hres = IHTMLWindow2_get_frames(window, &frames);
9155     ok(hres == S_OK, "IHTMLWindow2_get_frames failed: 0x%08x\n", hres);
9156     if(FAILED(hres))
9157         return;
9158 
9159     test_frames_collection(frames, "fr1");
9160     IHTMLFramesCollection2_Release(frames);
9161 
9162     hres = IHTMLDocument2_get_frames(doc, &frames);
9163     ok(hres == S_OK, "IHTMLDocument2_get_frames failed: 0x%08x\n", hres);
9164     if(FAILED(hres))
9165         return;
9166 
9167     test_frames_collection(frames, "fr1");
9168     IHTMLFramesCollection2_Release(frames);
9169 
9170     /* test using IHTMLWindow2 inheritance */
9171     test_frames_collection((IHTMLFramesCollection2*)window, "fr2");
9172 
9173     /* getElementById with node name attributes */
9174     elem = get_doc_elem_by_id(doc, "nm1");
9175     test_elem_id((IUnknown*)elem, "fr1");
9176 
9177     test_framebase((IUnknown*)elem);
9178     test_framebase_name(elem, "nm1");
9179     test_framebase_put_name(elem, "frame name");
9180     test_framebase_put_name(elem, NULL);
9181     test_framebase_put_name(elem, "nm1");
9182     test_framebase_src(elem, "about:blank");
9183     IHTMLElement_Release(elem);
9184 
9185     /* get_name with no name attr */
9186     elem = get_doc_elem_by_id(doc, "fr3");
9187     test_framebase_name(elem, NULL);
9188     test_framebase_put_name(elem, "frame name");
9189     test_framebase_put_name(elem, NULL);
9190     IHTMLElement_Release(elem);
9191 
9192     IHTMLWindow2_Release(window);
9193 }
9194 
create_docfrag(IHTMLDocument2 * doc)9195 static IHTMLDocument2 *create_docfrag(IHTMLDocument2 *doc)
9196 {
9197     IHTMLDocument2 *frag;
9198     IHTMLDocument3 *doc3;
9199     HRESULT hres;
9200 
9201     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
9202     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
9203 
9204     hres = IHTMLDocument3_createDocumentFragment(doc3, &frag);
9205     IHTMLDocument3_Release(doc3);
9206     ok(hres == S_OK, "createDocumentFragment failed: %08x\n", hres);
9207     ok(frag != NULL, "frag == NULL\n");
9208 
9209     return frag;
9210 }
9211 
test_docfrag(IHTMLDocument2 * doc)9212 static void test_docfrag(IHTMLDocument2 *doc)
9213 {
9214     IHTMLDocument2 *frag, *owner_doc, *doc_node;
9215     IHTMLElement *div, *body, *br;
9216     IHTMLElementCollection *col;
9217     IHTMLLocation *location;
9218     HRESULT hres;
9219 
9220     static const elem_type_t all_types[] = {
9221         ET_HTML,
9222         ET_HEAD,
9223         ET_TITLE,
9224         ET_BODY,
9225         ET_DIV,
9226         ET_BR
9227     };
9228 
9229     frag = create_docfrag(doc);
9230 
9231     test_disp((IUnknown*)frag, &DIID_DispHTMLDocument, "[object]");
9232 
9233     body = (void*)0xdeadbeef;
9234     hres = IHTMLDocument2_get_body(frag, &body);
9235     ok(hres == S_OK, "get_body failed: %08x\n", hres);
9236     ok(!body, "body != NULL\n");
9237 
9238     location = (void*)0xdeadbeef;
9239     hres = IHTMLDocument2_get_location(frag, &location);
9240     ok(hres == E_UNEXPECTED, "get_location failed: %08x\n", hres);
9241     ok(location == (void*)0xdeadbeef, "location changed\n");
9242 
9243     br = test_create_elem(doc, "BR");
9244     test_elem_source_index(br, -1);
9245     test_node_append_child((IUnknown*)frag, (IUnknown*)br);
9246     test_elem_source_index(br, 0);
9247     IHTMLElement_Release(br);
9248 
9249     div = get_elem_by_id(doc, "divid", TRUE);
9250     test_node_append_child((IUnknown*)div, (IUnknown*)frag);
9251     IHTMLElement_Release(div);
9252 
9253     hres = IHTMLDocument2_get_all(doc, &col);
9254     ok(hres == S_OK, "get_all failed: %08x\n", hres);
9255     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
9256     IHTMLElementCollection_Release(col);
9257 
9258     div = test_create_elem(frag, "div");
9259     owner_doc = get_owner_doc((IUnknown*)div);
9260     doc_node = get_doc_node(doc);
9261     ok(iface_cmp((IUnknown*)owner_doc, (IUnknown*)doc_node), "owner_doc != doc_node\n");
9262     IHTMLDocument2_Release(doc_node);
9263     IHTMLDocument2_Release(owner_doc);
9264     IHTMLElement_Release(div);
9265 
9266     IHTMLDocument2_Release(frag);
9267 }
9268 
check_quirks_mode(IHTMLDocument2 * doc)9269 static void check_quirks_mode(IHTMLDocument2 *doc)
9270 {
9271     test_compatmode(doc, "BackCompat");
9272 }
9273 
check_strict_mode(IHTMLDocument2 * doc)9274 static void check_strict_mode(IHTMLDocument2 *doc)
9275 {
9276     test_compatmode(doc, "CSS1Compat");
9277 }
9278 
test_quirks_mode_offsetHeight(IHTMLDocument2 * doc)9279 static void test_quirks_mode_offsetHeight(IHTMLDocument2 *doc)
9280 {
9281     IHTMLElement *elem;
9282     HRESULT hres;
9283     LONG oh;
9284 
9285     hres = IHTMLDocument2_get_body(doc, &elem);
9286     ok(hres == S_OK, "get_body fauled: %08x\n", hres);
9287 
9288     /* body.offsetHeight value depends on window size in quirks mode */
9289     hres = IHTMLElement_get_offsetHeight(elem, &oh);
9290     ok(hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
9291     todo_wine ok(oh == 500, "offsetHeight = %d\n", oh);
9292     IHTMLElement_Release(elem);
9293 }
9294 
9295 static IHTMLDocument2 *notif_doc;
9296 static BOOL doc_complete;
9297 
PropertyNotifySink_QueryInterface(IPropertyNotifySink * iface,REFIID riid,void ** ppv)9298 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
9299         REFIID riid, void**ppv)
9300 {
9301     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
9302         *ppv = iface;
9303         return S_OK;
9304     }
9305 
9306     ok(0, "unexpected call\n");
9307     return E_NOINTERFACE;
9308 }
9309 
PropertyNotifySink_AddRef(IPropertyNotifySink * iface)9310 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
9311 {
9312     return 2;
9313 }
9314 
PropertyNotifySink_Release(IPropertyNotifySink * iface)9315 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
9316 {
9317     return 1;
9318 }
9319 
PropertyNotifySink_OnChanged(IPropertyNotifySink * iface,DISPID dispID)9320 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
9321 {
9322     if(dispID == DISPID_READYSTATE){
9323         BSTR state;
9324         HRESULT hres;
9325 
9326         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
9327         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
9328 
9329         if(!strcmp_wa(state, "complete"))
9330             doc_complete = TRUE;
9331 
9332         SysFreeString(state);
9333     }
9334 
9335     return S_OK;
9336 }
9337 
PropertyNotifySink_OnRequestEdit(IPropertyNotifySink * iface,DISPID dispID)9338 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
9339 {
9340     ok(0, "unexpected call\n");
9341     return E_NOTIMPL;
9342 }
9343 
9344 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
9345     PropertyNotifySink_QueryInterface,
9346     PropertyNotifySink_AddRef,
9347     PropertyNotifySink_Release,
9348     PropertyNotifySink_OnChanged,
9349     PropertyNotifySink_OnRequestEdit
9350 };
9351 
9352 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
9353 
9354 static HRESULT cs_qi(REFIID,void **);
9355 static IOleDocumentView *view;
9356 static HWND container_hwnd;
9357 
InPlaceFrame_QueryInterface(IOleInPlaceFrame * iface,REFIID riid,void ** ppv)9358 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
9359 {
9360     static const GUID undocumented_frame_iid = {0xfbece6c9,0x48d7,0x4a37,{0x8f,0xe3,0x6a,0xd4,0x27,0x2f,0xdd,0xac}};
9361 
9362     if(!IsEqualGUID(&undocumented_frame_iid, riid))
9363         ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
9364 
9365     *ppv = NULL;
9366     return E_NOINTERFACE;
9367 }
9368 
InPlaceFrame_AddRef(IOleInPlaceFrame * iface)9369 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
9370 {
9371     return 2;
9372 }
9373 
InPlaceFrame_Release(IOleInPlaceFrame * iface)9374 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
9375 {
9376     return 1;
9377 }
9378 
InPlaceFrame_GetWindow(IOleInPlaceFrame * iface,HWND * phwnd)9379 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
9380 {
9381     return E_NOTIMPL;
9382 }
9383 
InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame * iface,BOOL fEnterMode)9384 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
9385 {
9386     return E_NOTIMPL;
9387 }
9388 
InPlaceFrame_GetBorder(IOleInPlaceFrame * iface,LPRECT lprectBorder)9389 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
9390 {
9391     return E_NOTIMPL;
9392 }
9393 
InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame * iface,LPCBORDERWIDTHS pborderwidths)9394 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
9395         LPCBORDERWIDTHS pborderwidths)
9396 {
9397     return E_NOTIMPL;
9398 }
9399 
InPlaceFrame_SetBorderSpace(IOleInPlaceFrame * iface,LPCBORDERWIDTHS pborderwidths)9400 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
9401         LPCBORDERWIDTHS pborderwidths)
9402 {
9403     return S_OK;
9404 }
9405 
InPlaceFrame_SetActiveObject(IOleInPlaceFrame * iface,IOleInPlaceActiveObject * pActiveObject,LPCOLESTR pszObjName)9406 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
9407         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
9408 {
9409     return S_OK;
9410 }
9411 
InPlaceFrame_InsertMenus(IOleInPlaceFrame * iface,HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths)9412 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
9413         LPOLEMENUGROUPWIDTHS lpMenuWidths)
9414 {
9415     return E_NOTIMPL;
9416 }
9417 
InPlaceFrame_SetMenu(IOleInPlaceFrame * iface,HMENU hmenuShared,HOLEMENU holemenu,HWND hwndActiveObject)9418 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
9419         HOLEMENU holemenu, HWND hwndActiveObject)
9420 {
9421     ok(0, "unexpected call\n");
9422     return E_NOTIMPL;
9423 }
9424 
InPlaceFrame_RemoveMenus(IOleInPlaceFrame * iface,HMENU hmenuShared)9425 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
9426 {
9427     ok(0, "unexpected call\n");
9428     return E_NOTIMPL;
9429 }
9430 
InPlaceFrame_SetStatusText(IOleInPlaceFrame * iface,LPCOLESTR pszStatusText)9431 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
9432 {
9433     return S_OK;
9434 }
9435 
InPlaceFrame_EnableModeless(IOleInPlaceFrame * iface,BOOL fEnable)9436 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
9437 {
9438     return E_NOTIMPL;
9439 }
9440 
InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame * iface,LPMSG lpmsg,WORD wID)9441 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
9442 {
9443     ok(0, "unexpected call\n");
9444     return E_NOTIMPL;
9445 }
9446 
9447 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
9448     InPlaceFrame_QueryInterface,
9449     InPlaceFrame_AddRef,
9450     InPlaceFrame_Release,
9451     InPlaceFrame_GetWindow,
9452     InPlaceFrame_ContextSensitiveHelp,
9453     InPlaceFrame_GetBorder,
9454     InPlaceFrame_RequestBorderSpace,
9455     InPlaceFrame_SetBorderSpace,
9456     InPlaceFrame_SetActiveObject,
9457     InPlaceFrame_InsertMenus,
9458     InPlaceFrame_SetMenu,
9459     InPlaceFrame_RemoveMenus,
9460     InPlaceFrame_SetStatusText,
9461     InPlaceFrame_EnableModeless,
9462     InPlaceFrame_TranslateAccelerator
9463 };
9464 
9465 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
9466 
InPlaceSite_QueryInterface(IOleInPlaceSite * iface,REFIID riid,void ** ppv)9467 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
9468 {
9469     return cs_qi(riid, ppv);
9470 }
9471 
InPlaceSite_AddRef(IOleInPlaceSite * iface)9472 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
9473 {
9474     return 2;
9475 }
9476 
InPlaceSite_Release(IOleInPlaceSite * iface)9477 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
9478 {
9479     return 1;
9480 }
9481 
InPlaceSite_GetWindow(IOleInPlaceSite * iface,HWND * phwnd)9482 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
9483 {
9484     *phwnd = container_hwnd;
9485     return S_OK;
9486 }
9487 
InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite * iface,BOOL fEnterMode)9488 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
9489 {
9490     ok(0, "unexpected call\n");
9491     return E_NOTIMPL;
9492 }
9493 
InPlaceSite_CanInPlaceActivate(IOleInPlaceSite * iface)9494 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
9495 {
9496     return S_OK;
9497 }
9498 
InPlaceSite_OnInPlaceActivate(IOleInPlaceSite * iface)9499 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
9500 {
9501     return S_OK;
9502 }
9503 
InPlaceSite_OnUIActivate(IOleInPlaceSite * iface)9504 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
9505 {
9506     return S_OK;
9507 }
9508 
InPlaceSite_GetWindowContext(IOleInPlaceSite * iface,IOleInPlaceFrame ** ppFrame,IOleInPlaceUIWindow ** ppDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo)9509 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
9510         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
9511                 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
9512 {
9513     static const RECT rect = {0,0,500,500};
9514 
9515     *ppFrame = &InPlaceFrame;
9516     *ppDoc = NULL;
9517     *lprcPosRect = rect;
9518     *lprcClipRect = rect;
9519 
9520     lpFrameInfo->fMDIApp = FALSE;
9521     lpFrameInfo->hwndFrame = container_hwnd;
9522     lpFrameInfo->haccel = NULL;
9523     lpFrameInfo->cAccelEntries = 0;
9524 
9525     return S_OK;
9526 }
9527 
InPlaceSite_Scroll(IOleInPlaceSite * iface,SIZE scrollExtant)9528 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
9529 {
9530     return E_NOTIMPL;
9531 }
9532 
InPlaceSite_OnUIDeactivate(IOleInPlaceSite * iface,BOOL fUndoable)9533 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
9534 {
9535     return S_OK;
9536 }
9537 
InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite * iface)9538 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
9539 {
9540     return S_OK;
9541 }
9542 
InPlaceSite_DiscardUndoState(IOleInPlaceSite * iface)9543 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
9544 {
9545     return E_NOTIMPL;
9546 }
9547 
InPlaceSite_DeactivateAndUndo(IOleInPlaceSite * iface)9548 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
9549 {
9550     return E_NOTIMPL;
9551 }
9552 
InPlaceSite_OnPosRectChange(IOleInPlaceSite * iface,LPCRECT lprcPosRect)9553 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
9554 {
9555     return E_NOTIMPL;
9556 }
9557 
9558 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
9559     InPlaceSite_QueryInterface,
9560     InPlaceSite_AddRef,
9561     InPlaceSite_Release,
9562     InPlaceSite_GetWindow,
9563     InPlaceSite_ContextSensitiveHelp,
9564     InPlaceSite_CanInPlaceActivate,
9565     InPlaceSite_OnInPlaceActivate,
9566     InPlaceSite_OnUIActivate,
9567     InPlaceSite_GetWindowContext,
9568     InPlaceSite_Scroll,
9569     InPlaceSite_OnUIDeactivate,
9570     InPlaceSite_OnInPlaceDeactivate,
9571     InPlaceSite_DiscardUndoState,
9572     InPlaceSite_DeactivateAndUndo,
9573     InPlaceSite_OnPosRectChange,
9574 };
9575 
9576 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
9577 
ClientSite_QueryInterface(IOleClientSite * iface,REFIID riid,void ** ppv)9578 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
9579 {
9580     return cs_qi(riid, ppv);
9581 }
9582 
ClientSite_AddRef(IOleClientSite * iface)9583 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
9584 {
9585     return 2;
9586 }
9587 
ClientSite_Release(IOleClientSite * iface)9588 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
9589 {
9590     return 1;
9591 }
9592 
ClientSite_SaveObject(IOleClientSite * iface)9593 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
9594 {
9595     ok(0, "unexpected call\n");
9596     return E_NOTIMPL;
9597 }
9598 
ClientSite_GetMoniker(IOleClientSite * iface,DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmon)9599 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
9600         IMoniker **ppmon)
9601 {
9602     ok(0, "unexpected call\n");
9603     return E_NOTIMPL;
9604 }
9605 
ClientSite_GetContainer(IOleClientSite * iface,IOleContainer ** ppContainer)9606 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
9607 {
9608     return E_NOTIMPL;
9609 }
9610 
ClientSite_ShowObject(IOleClientSite * iface)9611 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
9612 {
9613     ok(0, "unexpected call\n");
9614     return E_NOTIMPL;
9615 }
9616 
ClientSite_OnShowWindow(IOleClientSite * iface,BOOL fShow)9617 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
9618 {
9619     ok(0, "unexpected call\n");
9620     return E_NOTIMPL;
9621 }
9622 
ClientSite_RequestNewObjectLayout(IOleClientSite * iface)9623 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
9624 {
9625     ok(0, "unexpected call\n");
9626     return E_NOTIMPL;
9627 }
9628 
9629 static const IOleClientSiteVtbl ClientSiteVtbl = {
9630     ClientSite_QueryInterface,
9631     ClientSite_AddRef,
9632     ClientSite_Release,
9633     ClientSite_SaveObject,
9634     ClientSite_GetMoniker,
9635     ClientSite_GetContainer,
9636     ClientSite_ShowObject,
9637     ClientSite_OnShowWindow,
9638     ClientSite_RequestNewObjectLayout
9639 };
9640 
9641 static IOleClientSite ClientSite = { &ClientSiteVtbl };
9642 
DocumentSite_QueryInterface(IOleDocumentSite * iface,REFIID riid,void ** ppv)9643 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
9644 {
9645     return cs_qi(riid, ppv);
9646 }
9647 
DocumentSite_AddRef(IOleDocumentSite * iface)9648 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
9649 {
9650     return 2;
9651 }
9652 
DocumentSite_Release(IOleDocumentSite * iface)9653 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
9654 {
9655     return 1;
9656 }
9657 
DocumentSite_ActivateMe(IOleDocumentSite * iface,IOleDocumentView * pViewToActivate)9658 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
9659 {
9660     RECT rect = {0,0,500,500};
9661     IOleDocument *document;
9662     HRESULT hres;
9663 
9664     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
9665     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
9666 
9667     hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
9668     IOleDocument_Release(document);
9669     ok(hres == S_OK, "CreateView failed: %08x\n", hres);
9670 
9671     hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
9672     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
9673 
9674     hres = IOleDocumentView_UIActivate(view, TRUE);
9675     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
9676 
9677     hres = IOleDocumentView_SetRect(view, &rect);
9678     ok(hres == S_OK, "SetRect failed: %08x\n", hres);
9679 
9680     hres = IOleDocumentView_Show(view, TRUE);
9681     ok(hres == S_OK, "Show failed: %08x\n", hres);
9682 
9683     return S_OK;
9684 }
9685 
9686 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
9687     DocumentSite_QueryInterface,
9688     DocumentSite_AddRef,
9689     DocumentSite_Release,
9690     DocumentSite_ActivateMe
9691 };
9692 
9693 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
9694 
cs_qi(REFIID riid,void ** ppv)9695 static HRESULT cs_qi(REFIID riid, void **ppv)
9696 {
9697     *ppv = NULL;
9698 
9699     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
9700         *ppv = &ClientSite;
9701     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
9702         *ppv = &DocumentSite;
9703     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
9704         *ppv = &InPlaceSite;
9705 
9706     return *ppv ? S_OK : E_NOINTERFACE;
9707 }
9708 
set_client_site(IHTMLDocument2 * doc,BOOL set)9709 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
9710 {
9711     IOleObject *oleobj;
9712     HRESULT hres;
9713 
9714     if(!set && view) {
9715         IOleDocumentView_Show(view, FALSE);
9716         IOleDocumentView_CloseView(view, 0);
9717         IOleDocumentView_SetInPlaceSite(view, NULL);
9718         IOleDocumentView_Release(view);
9719         view = NULL;
9720     }
9721 
9722     hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
9723     ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
9724 
9725     hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
9726     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
9727 
9728     if(set) {
9729         IHlinkTarget *hlink;
9730 
9731         hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
9732         ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
9733 
9734         hres = IHlinkTarget_Navigate(hlink, 0, NULL);
9735         ok(hres == S_OK, "Navgate failed: %08x\n", hres);
9736 
9737         IHlinkTarget_Release(hlink);
9738     }
9739 
9740     IOleObject_Release(oleobj);
9741 }
9742 
create_doc_with_string(const char * str)9743 static IHTMLDocument2 *create_doc_with_string(const char *str)
9744 {
9745     IPersistStreamInit *init;
9746     IStream *stream;
9747     IHTMLDocument2 *doc;
9748     HGLOBAL mem;
9749     SIZE_T len;
9750 
9751     notif_doc = doc = create_document();
9752     if(!doc)
9753         return NULL;
9754 
9755     doc_complete = FALSE;
9756     len = strlen(str);
9757     mem = GlobalAlloc(0, len);
9758     memcpy(mem, str, len);
9759     CreateStreamOnHGlobal(mem, TRUE, &stream);
9760 
9761     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
9762 
9763     IPersistStreamInit_Load(init, stream);
9764     IPersistStreamInit_Release(init);
9765     IStream_Release(stream);
9766 
9767     return doc;
9768 }
9769 
do_advise(IUnknown * unk,REFIID riid,IUnknown * unk_advise)9770 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
9771 {
9772     IConnectionPointContainer *container;
9773     IConnectionPoint *cp;
9774     DWORD cookie;
9775     HRESULT hres;
9776 
9777     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
9778     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
9779 
9780     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
9781     IConnectionPointContainer_Release(container);
9782     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
9783 
9784     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
9785     IConnectionPoint_Release(cp);
9786     ok(hres == S_OK, "Advise failed: %08x\n", hres);
9787 }
9788 
9789 typedef void (*domtest_t)(IHTMLDocument2*);
9790 
run_domtest(const char * str,domtest_t test)9791 static void run_domtest(const char *str, domtest_t test)
9792 {
9793     IHTMLDocument2 *doc;
9794     ULONG ref;
9795     MSG msg;
9796 
9797     doc = create_doc_with_string(str);
9798     if(!doc)
9799         return;
9800 
9801     set_client_site(doc, TRUE);
9802     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
9803 
9804     while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) {
9805         TranslateMessage(&msg);
9806         DispatchMessageW(&msg);
9807     }
9808 
9809     test(doc);
9810 
9811     set_client_site(doc, FALSE);
9812     ref = IHTMLDocument2_Release(doc);
9813     ok(!ref || broken(ref == 1), /* Vista */
9814        "ref = %d\n", ref);
9815 }
9816 
test_quirks_mode(void)9817 static void test_quirks_mode(void)
9818 {
9819     run_domtest("<html></html>", check_quirks_mode);
9820     run_domtest("<!DOCTYPE html>\n<html></html>", check_strict_mode);
9821     run_domtest("<!-- comment --><!DOCTYPE html>\n<html></html>", check_quirks_mode);
9822     run_domtest("<html><body></body></html>", test_quirks_mode_offsetHeight);
9823 }
9824 
START_TEST(dom)9825 START_TEST(dom)
9826 {
9827     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
9828     pLCIDToLocaleName = (void*)GetProcAddress(hkernel32, "LCIDToLocaleName");
9829     pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
9830 
9831     CoInitialize(NULL);
9832     container_hwnd = CreateWindowA("static", NULL, WS_POPUP|WS_VISIBLE,
9833             CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, NULL, NULL);
9834 
9835     run_domtest(doc_str1, test_doc_elem);
9836     run_domtest(doc_str1, test_get_set_attr);
9837     run_domtest(range_test_str, test_txtrange);
9838     run_domtest(range_test2_str, test_txtrange2);
9839     if (winetest_interactive || ! is_ie_hardened()) {
9840         run_domtest(elem_test_str, test_elems);
9841         run_domtest(elem_test2_str, test_elems2);
9842         run_domtest(noscript_str, test_noscript);
9843     }else {
9844         skip("IE running in Enhanced Security Configuration\n");
9845     }
9846     run_domtest(doc_blank, test_create_elems);
9847     run_domtest(doc_blank, test_defaults);
9848     run_domtest(doc_blank, test_null_write);
9849     run_domtest(emptydiv_str, test_create_stylesheet);
9850     run_domtest(indent_test_str, test_indent);
9851     run_domtest(cond_comment_str, test_cond_comment);
9852     run_domtest(frameset_str, test_frameset);
9853     run_domtest(emptydiv_str, test_docfrag);
9854     run_domtest(doc_blank, test_replacechild_elems);
9855     run_domtest(doctype_str, test_doctype);
9856 
9857     test_quirks_mode();
9858 
9859     DestroyWindow(container_hwnd);
9860     CoUninitialize();
9861 }
9862