[MSHTML_WINETEST]
[reactos.git] / rostests / winetests / mshtml / dom.c
1 /*
2 * Copyright 2007-2011 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 //#include <stdarg.h>
24 #include <stdio.h>
25
26 //#include "windef.h"
27 //#include "winbase.h"
28 //#include "ole2.h"
29 #include <mshtml.h>
30 #include <mshtmcid.h>
31 #include <mshtmhst.h>
32 //#include "docobj.h"
33 //#include "dispex.h"
34 #include "mshtml_test.h"
35 #include <objsafe.h>
36 #include <htiface.h>
37 #include <tlogstg.h>
38
39 static INT (WINAPI *pLCIDToLocaleName)(LCID,LPWSTR,INT,DWORD);
40 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void);
41
42 static const char doc_blank[] = "<html></html>";
43 static const char doc_str1[] = "<html><body>test</body></html>";
44 static const char range_test_str[] =
45 "<html><body>test \na<font size=\"2\">bc\t123<br /> it's\r\n \t</font>text<br /></body></html>";
46 static const char range_test2_str[] =
47 "<html><body>abc<hr />123<br /><hr />def</body></html>";
48 static const char elem_test_str[] =
49 "<html><head><title>test</title><style id=\"styleid\">.body { margin-right: 0px; }</style>"
50 "<meta id=\"metaid\" name=\"meta name\" http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
51 "<link id=\"linkid\"></head>"
52 "<body onload=\"Testing()\">text test<!-- a comment -->"
53 "<a id=\"a\" href=\"http://test\" name=\"x\">link</a>"
54 "<label for=\"in\" id=\"labelid\">Label:</label>"
55 "<input id=\"in\" class=\"testclass\" tabIndex=\"2\" title=\"test title\" />"
56 "<button id=\"btnid\"></button>"
57 "<select id=\"s\"><option id=\"x\" value=\"val1\">opt1</option><option id=\"y\">opt2</option></select>"
58 "<textarea id=\"X\">text text</textarea>"
59 "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td id=\"td1\">td1 text</td><td id=\"td2\">td2 text</td></tr></tbody></table>"
60 "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
61 "<test /><object id=\"objid\" name=\"objname\" vspace=100></object><embed />"
62 "<img id=\"imgid\" name=\"WineImg\"/>"
63 "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
64 "<form id=\"frm\"></form>"
65 "<div id=\"attr\" attr1=\"attr1\" attr2 attr3=\"attr3\"></div>"
66 "</body></html>";
67 static const char elem_test2_str[] =
68 "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
69 "<link id=\"linkid\" rel=\"stylesheet\" href=\"about:blank\" type=\"text/css\"></head>"
70 "<body><div id=\"divid\" emptyattr=\"\" onclick=\"parseInt();\"></div></body>"
71 "</html>";
72
73 static const char indent_test_str[] =
74 "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
75 static const char cond_comment_str[] =
76 "<html><head><title>test</title></head><body>"
77 "<!--[if gte IE 4]> <br> <![endif]-->"
78 "</body></html>";
79 static const char frameset_str[] =
80 "<html><head><title>frameset test</title></head><frameset rows=\"25, 25, *\">"
81 "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
82 "<frame src=\"about:blank\" id=\"fr3\">"
83 "</frameset></html>";
84 static const char emptydiv_str[] =
85 "<html><head><title>emptydiv test</title></head>"
86 "<body><div id=\"divid\"></div></body></html>";
87 static const char noscript_str[] =
88 "<html><head><title>noscript test</title><noscript><style>.body { margin-right: 0px; }</style></noscript></head>"
89 "<body><noscript><div>test</div></noscript></body></html>";
90 static const char doctype_str[] =
91 "<!DOCTYPE html>"
92 "<html><head><title>emptydiv test</title></head>"
93 "<body><div id=\"divid\"></div></body></html>";
94
95 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
96 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
97 static WCHAR wordW[] = {'w','o','r','d',0};
98
99 typedef enum {
100 ET_NONE,
101 ET_HTML,
102 ET_HEAD,
103 ET_TITLE,
104 ET_BODY,
105 ET_A,
106 ET_INPUT,
107 ET_SELECT,
108 ET_TEXTAREA,
109 ET_OPTION,
110 ET_STYLE,
111 ET_BLOCKQUOTE,
112 ET_P,
113 ET_BR,
114 ET_TABLE,
115 ET_TBODY,
116 ET_SCRIPT,
117 ET_TEST,
118 ET_TESTG,
119 ET_COMMENT,
120 ET_IMG,
121 ET_TR,
122 ET_TD,
123 ET_IFRAME,
124 ET_FORM,
125 ET_FRAME,
126 ET_OBJECT,
127 ET_EMBED,
128 ET_DIV,
129 ET_META,
130 ET_NOSCRIPT,
131 ET_LINK,
132 ET_LABEL,
133 ET_BUTTON
134 } elem_type_t;
135
136 static const IID * const none_iids[] = {
137 &IID_IUnknown,
138 NULL
139 };
140
141 static const IID * const doc_node_iids[] = {
142 &IID_IHTMLDOMNode,
143 &IID_IHTMLDOMNode2,
144 &IID_IHTMLDocument,
145 &IID_IHTMLDocument2,
146 &IID_IHTMLDocument3,
147 &IID_IHTMLDocument4,
148 &IID_IHTMLDocument5,
149 &IID_IDispatchEx,
150 &IID_IConnectionPointContainer,
151 &IID_IInternetHostSecurityManager,
152 &IID_IOleContainer,
153 &IID_IObjectSafety,
154 &IID_IProvideClassInfo,
155 NULL
156 };
157
158 static const IID * const doc_obj_iids[] = {
159 &IID_IHTMLDocument,
160 &IID_IHTMLDocument2,
161 &IID_IHTMLDocument3,
162 &IID_IHTMLDocument4,
163 &IID_IHTMLDocument5,
164 &IID_IDispatchEx,
165 &IID_IConnectionPointContainer,
166 &IID_ICustomDoc,
167 &IID_IOleContainer,
168 &IID_IObjectSafety,
169 &IID_IProvideClassInfo,
170 &IID_ITargetContainer,
171 NULL
172 };
173
174 #define ELEM_IFACES \
175 &IID_IHTMLDOMNode, \
176 &IID_IHTMLDOMNode2, \
177 &IID_IHTMLElement, \
178 &IID_IHTMLElement2, \
179 &IID_IHTMLElement3, \
180 &IID_IHTMLElement4, \
181 &IID_IDispatchEx
182
183 static const IID * const elem_iids[] = {
184 ELEM_IFACES,
185 &IID_IConnectionPointContainer,
186 NULL
187 };
188
189 static const IID * const body_iids[] = {
190 ELEM_IFACES,
191 &IID_IHTMLTextContainer,
192 &IID_IHTMLBodyElement,
193 &IID_IConnectionPointContainer,
194 NULL
195 };
196
197 static const IID * const anchor_iids[] = {
198 ELEM_IFACES,
199 &IID_IHTMLAnchorElement,
200 &IID_IConnectionPointContainer,
201 NULL
202 };
203
204 static const IID * const input_iids[] = {
205 ELEM_IFACES,
206 &IID_IHTMLInputElement,
207 &IID_IHTMLInputTextElement,
208 &IID_IConnectionPointContainer,
209 NULL
210 };
211
212 static const IID *const button_iids[] = {
213 ELEM_IFACES,
214 &IID_IHTMLButtonElement,
215 &IID_IConnectionPointContainer,
216 NULL
217 };
218
219 static const IID * const label_iids[] = {
220 ELEM_IFACES,
221 &IID_IHTMLLabelElement,
222 &IID_IConnectionPointContainer,
223 NULL
224 };
225
226 static const IID * const select_iids[] = {
227 ELEM_IFACES,
228 &IID_IHTMLSelectElement,
229 &IID_IConnectionPointContainer,
230 NULL
231 };
232
233 static const IID * const textarea_iids[] = {
234 ELEM_IFACES,
235 &IID_IHTMLTextAreaElement,
236 &IID_IConnectionPointContainer,
237 NULL
238 };
239
240 static const IID * const option_iids[] = {
241 ELEM_IFACES,
242 &IID_IHTMLOptionElement,
243 &IID_IConnectionPointContainer,
244 NULL
245 };
246
247 static const IID * const table_iids[] = {
248 ELEM_IFACES,
249 &IID_IHTMLTable,
250 &IID_IHTMLTable2,
251 &IID_IHTMLTable3,
252 &IID_IConnectionPointContainer,
253 NULL
254 };
255
256 static const IID * const script_iids[] = {
257 ELEM_IFACES,
258 &IID_IHTMLScriptElement,
259 &IID_IConnectionPointContainer,
260 NULL
261 };
262
263 static const IID * const text_iids[] = {
264 &IID_IHTMLDOMNode,
265 &IID_IHTMLDOMNode2,
266 &IID_IHTMLDOMTextNode,
267 NULL
268 };
269
270 static const IID * const attr_iids[] = {
271 &IID_IHTMLDOMAttribute,
272 &IID_IDispatchEx,
273 NULL
274 };
275
276 static const IID * const location_iids[] = {
277 &IID_IDispatch,
278 &IID_IHTMLLocation,
279 NULL
280 };
281
282 static const IID * const window_iids[] = {
283 &IID_IDispatch,
284 &IID_IHTMLWindow2,
285 &IID_IHTMLWindow3,
286 &IID_IDispatchEx,
287 &IID_IServiceProvider,
288 NULL
289 };
290
291 static const IID * const comment_iids[] = {
292 ELEM_IFACES,
293 &IID_IHTMLCommentElement,
294 &IID_IConnectionPointContainer,
295 NULL
296 };
297
298 static const IID * const img_iids[] = {
299 ELEM_IFACES,
300 &IID_IHTMLImgElement,
301 &IID_IConnectionPointContainer,
302 NULL
303 };
304
305 static const IID * const tr_iids[] = {
306 ELEM_IFACES,
307 &IID_IHTMLTableRow,
308 &IID_IConnectionPointContainer,
309 NULL
310 };
311
312 static const IID * const td_iids[] = {
313 ELEM_IFACES,
314 &IID_IHTMLTableCell,
315 &IID_IConnectionPointContainer,
316 NULL
317 };
318
319 static const IID * const frame_iids[] = {
320 ELEM_IFACES,
321 &IID_IHTMLFrameBase,
322 &IID_IHTMLFrameBase2,
323 &IID_IConnectionPointContainer,
324 NULL
325 };
326
327 static const IID * const head_iids[] = {
328 ELEM_IFACES,
329 &IID_IHTMLHeadElement,
330 &IID_IConnectionPointContainer,
331 NULL
332 };
333
334 static const IID * const title_iids[] = {
335 ELEM_IFACES,
336 &IID_IHTMLTitleElement,
337 &IID_IConnectionPointContainer,
338 NULL
339 };
340
341 static const IID * const meta_iids[] = {
342 ELEM_IFACES,
343 &IID_IHTMLMetaElement,
344 &IID_IConnectionPointContainer,
345 NULL
346 };
347
348 static const IID * const link_iids[] = {
349 ELEM_IFACES,
350 &IID_IHTMLLinkElement,
351 &IID_IConnectionPointContainer,
352 NULL
353 };
354
355 static const IID * const object_iids[] = {
356 ELEM_IFACES,
357 &IID_IHTMLObjectElement,
358 &IID_IHTMLObjectElement2,
359 /* FIXME: No IConnectionPointContainer */
360 NULL
361 };
362
363 static const IID * const embed_iids[] = {
364 ELEM_IFACES,
365 &IID_IHTMLEmbedElement,
366 /* FIXME: No IConnectionPointContainer */
367 NULL
368 };
369
370 static const IID * const iframe_iids[] = {
371 ELEM_IFACES,
372 &IID_IHTMLFrameBase,
373 &IID_IHTMLFrameBase2,
374 &IID_IHTMLIFrameElement,
375 &IID_IHTMLIFrameElement2,
376 &IID_IConnectionPointContainer,
377 NULL
378 };
379
380 static const IID * const form_iids[] = {
381 ELEM_IFACES,
382 &IID_IHTMLFormElement,
383 &IID_IConnectionPointContainer,
384 NULL
385 };
386
387 static const IID * const styleelem_iids[] = {
388 ELEM_IFACES,
389 &IID_IHTMLStyleElement,
390 &IID_IConnectionPointContainer,
391 NULL
392 };
393
394 static const IID * const generic_iids[] = {
395 ELEM_IFACES,
396 &IID_IHTMLGenericElement,
397 &IID_IConnectionPointContainer,
398 NULL
399 };
400
401 static const IID * const style_iids[] = {
402 &IID_IUnknown,
403 &IID_IDispatch,
404 &IID_IDispatchEx,
405 &IID_IHTMLStyle,
406 &IID_IHTMLStyle2,
407 &IID_IHTMLStyle3,
408 &IID_IHTMLStyle4,
409 NULL
410 };
411
412 static const IID * const cstyle_iids[] = {
413 &IID_IUnknown,
414 &IID_IDispatch,
415 &IID_IDispatchEx,
416 &IID_IHTMLCurrentStyle,
417 &IID_IHTMLCurrentStyle2,
418 &IID_IHTMLCurrentStyle3,
419 NULL
420 };
421
422 static const IID * const img_factory_iids[] = {
423 &IID_IUnknown,
424 &IID_IDispatch,
425 &IID_IDispatchEx,
426 &IID_IHTMLImageElementFactory,
427 NULL
428 };
429
430 typedef struct {
431 const char *tag;
432 REFIID *iids;
433 const IID *dispiid;
434 } elem_type_info_t;
435
436 static const elem_type_info_t elem_type_infos[] = {
437 {"", none_iids, NULL},
438 {"HTML", elem_iids, NULL},
439 {"HEAD", head_iids, &DIID_DispHTMLHeadElement},
440 {"TITLE", title_iids, &DIID_DispHTMLTitleElement},
441 {"BODY", body_iids, &DIID_DispHTMLBody},
442 {"A", anchor_iids, &DIID_DispHTMLAnchorElement},
443 {"INPUT", input_iids, &DIID_DispHTMLInputElement},
444 {"SELECT", select_iids, &DIID_DispHTMLSelectElement},
445 {"TEXTAREA", textarea_iids, &DIID_DispHTMLTextAreaElement},
446 {"OPTION", option_iids, &DIID_DispHTMLOptionElement},
447 {"STYLE", styleelem_iids, &DIID_DispHTMLStyleElement},
448 {"BLOCKQUOTE",elem_iids, NULL},
449 {"P", elem_iids, NULL},
450 {"BR", elem_iids, NULL},
451 {"TABLE", table_iids, &DIID_DispHTMLTable},
452 {"TBODY", elem_iids, NULL},
453 {"SCRIPT", script_iids, &DIID_DispHTMLScriptElement},
454 {"TEST", elem_iids, &DIID_DispHTMLUnknownElement},
455 {"TEST", generic_iids, &DIID_DispHTMLGenericElement},
456 {"!", comment_iids, &DIID_DispHTMLCommentElement},
457 {"IMG", img_iids, &DIID_DispHTMLImg},
458 {"TR", tr_iids, &DIID_DispHTMLTableRow},
459 {"TD", td_iids, &DIID_DispHTMLTableCell},
460 {"IFRAME", iframe_iids, &DIID_DispHTMLIFrame},
461 {"FORM", form_iids, &DIID_DispHTMLFormElement},
462 {"FRAME", frame_iids, &DIID_DispHTMLFrameElement},
463 {"OBJECT", object_iids, &DIID_DispHTMLObjectElement},
464 {"EMBED", embed_iids, &DIID_DispHTMLEmbed},
465 {"DIV", elem_iids, NULL},
466 {"META", meta_iids, &DIID_DispHTMLMetaElement},
467 {"NOSCRIPT", elem_iids, NULL /*&DIID_DispHTMLNoShowElement*/},
468 {"LINK", link_iids, &DIID_DispHTMLLinkElement},
469 {"LABEL", label_iids, &DIID_DispHTMLLabelElement},
470 {"BUTTON", button_iids, &DIID_DispHTMLButtonElement}
471 };
472
473 static int strcmp_wa(LPCWSTR strw, const char *stra)
474 {
475 CHAR buf[512];
476 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
477 return lstrcmpA(stra, buf);
478 }
479
480 static BSTR a2bstr(const char *str)
481 {
482 BSTR ret;
483 int len;
484
485 if(!str)
486 return NULL;
487
488 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
489 ret = SysAllocStringLen(NULL, len);
490 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
491
492 return ret;
493 }
494
495 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
496 {
497 IUnknown *unk1, *unk2;
498
499 if(iface1 == iface2)
500 return TRUE;
501
502 IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
503 IUnknown_Release(unk1);
504 IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
505 IUnknown_Release(unk2);
506
507 return unk1 == unk2;
508 }
509
510 static IHTMLDocument2 *create_document(void)
511 {
512 IHTMLDocument2 *doc;
513 IHTMLDocument5 *doc5;
514 HRESULT hres;
515
516 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
517 &IID_IHTMLDocument2, (void**)&doc);
518 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
519 if(FAILED(hres))
520 return NULL;
521
522 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
523 if(FAILED(hres)) {
524 win_skip("Could not get IHTMLDocument5, probably too old IE\n");
525 IHTMLDocument2_Release(doc);
526 return NULL;
527 }
528
529 IHTMLDocument5_Release(doc5);
530 return doc;
531 }
532
533 #define get_dispex_iface(u) _get_dispex_iface(__LINE__,u)
534 static IDispatchEx *_get_dispex_iface(unsigned line, IUnknown *unk)
535 {
536 IDispatchEx *dispex;
537 HRESULT hres;
538
539 hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
540 ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
541 return dispex;
542 }
543
544 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
545 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
546 {
547 const IID * const *piid;
548 IUnknown *unk;
549 HRESULT hres;
550
551 for(piid = iids; *piid; piid++) {
552 hres = IUnknown_QueryInterface(iface, *piid, (void**)&unk);
553 ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", wine_dbgstr_guid(*piid), hres);
554 if(SUCCEEDED(hres))
555 IUnknown_Release(unk);
556 }
557 }
558
559 #define test_no_iface(a,b) _test_no_iface(__LINE__,a,b)
560 static void _test_no_iface(unsigned line, IUnknown *iface, REFIID iid)
561 {
562 IUnknown *unk;
563 HRESULT hres;
564
565 unk = (void*)0xdeadbeef;
566 hres = IUnknown_QueryInterface(iface, iid, (void**)&unk);
567 ok_(__FILE__,line)(hres == E_NOINTERFACE, "hres = %08x, expected E_NOINTERFACE\n", hres);
568 ok_(__FILE__,line)(!unk, "unk = %p\n", unk);
569 }
570
571 #define test_get_dispid(u,id) _test_get_dispid(__LINE__,u,id)
572 static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
573 {
574 IDispatchEx *dispex = _get_dispex_iface(line, unk);
575 ITypeInfo *typeinfo;
576 BOOL ret = FALSE;
577 UINT ticnt;
578 HRESULT hres;
579
580 ticnt = 0xdeadbeef;
581 hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
582 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
583 ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
584
585 hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
586 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
587
588 if(SUCCEEDED(hres)) {
589 TYPEATTR *type_attr;
590
591 hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
592 ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
593 if(hres == S_OK) {
594 *iid = type_attr->guid;
595 ret = TRUE;
596 }
597
598 ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
599 ITypeInfo_Release(typeinfo);
600 }
601
602 IDispatchEx_Release(dispex);
603 return ret;
604 }
605
606 #define test_disp_value(u) _test_disp_value(__LINE__,u,v)
607 static void _test_disp_value(unsigned line, IUnknown *unk, const char *val)
608 {
609 IDispatchEx *dispex = _get_dispex_iface(line, unk);
610 DISPPARAMS dp = {NULL,NULL,0,0};
611 EXCEPINFO ei;
612 VARIANT var;
613 HRESULT hres;
614
615 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
616 IDispatchEx_Release(dispex);
617 ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres);
618
619 ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var));
620 ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val);
621 VariantClear(&var);
622 }
623
624 #define test_disp(u,id,v) _test_disp(__LINE__,u,id,v)
625 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val)
626 {
627 IID iid;
628
629 if(_test_get_dispid(line, unk, &iid))
630 ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", wine_dbgstr_guid(&iid));
631
632 if(val)
633 _test_disp_value(line, unk, val);
634 }
635
636 #define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v)
637 static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val)
638 {
639 IID iid;
640
641 if(_test_get_dispid(line, unk, &iid))
642 ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)),
643 "unexpected guid %s\n", wine_dbgstr_guid(&iid));
644
645 if(val)
646 _test_disp_value(line, unk, val);
647 }
648
649 #define test_class_info(u) _test_class_info(__LINE__,u)
650 static void _test_class_info(unsigned line, IUnknown *unk)
651 {
652 IProvideClassInfo *classinfo;
653 ITypeInfo *typeinfo;
654 TYPEATTR *type_attr;
655 HRESULT hres;
656
657 hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo, (void**)&classinfo);
658 ok_(__FILE__,line)(hres == S_OK, "Could not get IProvideClassInfo interface: %08x\n", hres);
659 if(FAILED(hres))
660 return;
661
662 hres = IProvideClassInfo_GetClassInfo(classinfo, &typeinfo);
663 ok_(__FILE__,line)(hres == S_OK, "Could not get ITypeInfo interface: %08x\n", hres);
664 if(FAILED(hres))
665 {
666 IProvideClassInfo_Release(classinfo);
667 return;
668 }
669
670 hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
671 ok_(__FILE__,line)(hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
672 if(SUCCEEDED(hres))
673 {
674 ok_(__FILE__,line)(IsEqualGUID(&type_attr->guid, &CLSID_HTMLDocument),
675 "unexpected guid %s\n", wine_dbgstr_guid(&type_attr->guid));
676 ok_(__FILE__,line)(type_attr->typekind == TKIND_COCLASS,
677 "unexpected typekind %d\n", type_attr->typekind);
678 ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
679 }
680
681 ITypeInfo_Release(typeinfo);
682 IProvideClassInfo_Release(classinfo);
683 }
684
685 #define set_dispex_value(a,b,c) _set_dispex_value(__LINE__,a,b,c)
686 static void _set_dispex_value(unsigned line, IUnknown *unk, const char *name, VARIANT *val)
687 {
688 IDispatchEx *dispex = _get_dispex_iface(line, unk);
689 DISPPARAMS dp = {val, NULL, 1, 0};
690 EXCEPINFO ei;
691 DISPID id;
692 BSTR str;
693 HRESULT hres;
694
695 str = a2bstr(name);
696 hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure|fdexNameCaseInsensitive, &id);
697 SysFreeString(str);
698 ok_(__FILE__,line)(hres == S_OK, "GetDispID failed: %08x\n", hres);
699
700 memset(&ei, 0, sizeof(ei));
701 hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
702 ok_(__FILE__,line)(hres == S_OK, "InvokeEx failed: %08x\n", hres);
703
704 }
705
706 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
707 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
708 {
709 IHTMLElement *elem;
710 HRESULT hres;
711
712 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
713 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres);
714 return elem;
715 }
716
717 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
718 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
719 {
720 IHTMLElement2 *elem;
721 HRESULT hres;
722
723 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem);
724 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres);
725 return elem;
726 }
727
728 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
729 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
730 {
731 IHTMLElement3 *elem;
732 HRESULT hres;
733
734 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem);
735 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres);
736 return elem;
737 }
738
739 #define get_elem4_iface(u) _get_elem4_iface(__LINE__,u)
740 static IHTMLElement4 *_get_elem4_iface(unsigned line, IUnknown *unk)
741 {
742 IHTMLElement4 *elem;
743 HRESULT hres;
744
745 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement4, (void**)&elem);
746 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement4: %08x\n", hres);
747 return elem;
748 }
749
750 #define get_doc3_iface(u) _get_doc3_iface(__LINE__,u)
751 static IHTMLDocument3 *_get_doc3_iface(unsigned line, IHTMLDocument2 *doc)
752 {
753 IHTMLDocument3 *doc3;
754 HRESULT hres;
755
756 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
757 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
758
759 return doc3;
760 }
761
762 #define get_node_iface(u) _get_node_iface(__LINE__,u)
763 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
764 {
765 IHTMLDOMNode *node;
766 HRESULT hres;
767
768 hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node);
769 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres);
770 return node;
771 }
772
773 #define get_node2_iface(u) _get_node2_iface(__LINE__,u)
774 static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk)
775 {
776 IHTMLDOMNode2 *node;
777 HRESULT hres;
778
779 hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node);
780 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres);
781 return node;
782 }
783
784 #define get_htmldoc5_iface(u) _get_htmldoc5_iface(__LINE__,u)
785 static IHTMLDocument5 *_get_htmldoc5_iface(unsigned line, IUnknown *unk)
786 {
787 IHTMLDocument5 *doc;
788 HRESULT hres;
789
790 hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument5, (void**)&doc);
791 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument5: %08x\n", hres);
792 return doc;
793 }
794
795 #define get_img_iface(u) _get_img_iface(__LINE__,u)
796 static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk)
797 {
798 IHTMLImgElement *img;
799 HRESULT hres;
800
801 hres = IUnknown_QueryInterface(unk, &IID_IHTMLImgElement, (void**)&img);
802 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLImgElement: %08x\n", hres);
803 return img;
804 }
805
806 #define get_anchor_iface(u) _get_anchor_iface(__LINE__,u)
807 static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
808 {
809 IHTMLAnchorElement *anchor;
810 HRESULT hres;
811
812 hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor);
813 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres);
814 return anchor;
815 }
816
817 #define get_textarea_iface(u) _get_textarea_iface(__LINE__,u)
818 static IHTMLTextAreaElement *_get_textarea_iface(unsigned line, IUnknown *unk)
819 {
820 IHTMLTextAreaElement *textarea;
821 HRESULT hres;
822
823 hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextAreaElement, (void**)&textarea);
824 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextAreaElement: %08x\n", hres);
825 return textarea;
826 }
827
828 #define get_select_iface(u) _get_select_iface(__LINE__,u)
829 static IHTMLSelectElement *_get_select_iface(unsigned line, IUnknown *unk)
830 {
831 IHTMLSelectElement *select;
832 HRESULT hres;
833
834 hres = IUnknown_QueryInterface(unk, &IID_IHTMLSelectElement, (void**)&select);
835 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLSelectElement: %08x\n", hres);
836 return select;
837 }
838
839 #define get_form_iface(u) _get_form_iface(__LINE__,u)
840 static IHTMLFormElement *_get_form_iface(unsigned line, IUnknown *unk)
841 {
842 IHTMLFormElement *form;
843 HRESULT hres;
844
845 hres = IUnknown_QueryInterface(unk, &IID_IHTMLFormElement, (void**)&form);
846 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLFormElement: %08x\n", hres);
847 return form;
848 }
849
850 #define get_text_iface(u) _get_text_iface(__LINE__,u)
851 static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk)
852 {
853 IHTMLDOMTextNode *text;
854 HRESULT hres;
855
856 hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text);
857 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres);
858 return text;
859 }
860
861 #define get_comment_iface(u) _get_comment_iface(__LINE__,u)
862 static IHTMLCommentElement *_get_comment_iface(unsigned line, IUnknown *unk)
863 {
864 IHTMLCommentElement *comment;
865 HRESULT hres;
866
867 hres = IUnknown_QueryInterface(unk, &IID_IHTMLCommentElement, (void**)&comment);
868 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLCommentElement: %08x\n", hres);
869 return comment;
870 }
871
872 #define get_object_iface(u) _get_object_iface(__LINE__,u)
873 static IHTMLObjectElement *_get_object_iface(unsigned line, IUnknown *unk)
874 {
875 IHTMLObjectElement *obj;
876 HRESULT hres;
877
878 hres = IUnknown_QueryInterface(unk, &IID_IHTMLObjectElement, (void**)&obj);
879 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLObjectElement: %08x\n", hres);
880 return obj;
881 }
882
883 #define get_style_iface(u) _get_style_iface(__LINE__,u)
884 static IHTMLStyleElement *_get_style_iface(unsigned line, IUnknown *unk)
885 {
886 IHTMLStyleElement *obj;
887 HRESULT hres;
888
889 hres = IUnknown_QueryInterface(unk, &IID_IHTMLStyleElement, (void**)&obj);
890 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLStyleElement: %08x\n", hres);
891 return obj;
892 }
893
894 #define get_metaelem_iface(u) _get_metaelem_iface(__LINE__,u)
895 static IHTMLMetaElement *_get_metaelem_iface(unsigned line, IUnknown *unk)
896 {
897 IHTMLMetaElement *ret;
898 HRESULT hres;
899
900 hres = IUnknown_QueryInterface(unk, &IID_IHTMLMetaElement, (void**)&ret);
901 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLMetaElement: %08x\n", hres);
902 return ret;
903 }
904
905 #define get_link_iface(u) _get_link_iface(__LINE__,u)
906 static IHTMLLinkElement *_get_link_iface(unsigned line, IUnknown *unk)
907 {
908 IHTMLLinkElement *ret;
909 HRESULT hres;
910
911 hres = IUnknown_QueryInterface(unk, &IID_IHTMLLinkElement, (void**)&ret);
912 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLinkElement: %08x\n", hres);
913 return ret;
914 }
915
916 #define get_iframe2_iface(u) _get_iframe2_iface(__LINE__,u)
917 static IHTMLIFrameElement2 *_get_iframe2_iface(unsigned line, IUnknown *unk)
918 {
919 IHTMLIFrameElement2 *ret;
920 HRESULT hres;
921
922 hres = IUnknown_QueryInterface(unk, &IID_IHTMLIFrameElement2, (void**)&ret);
923 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLIFrameElement: %08x\n", hres);
924 return ret;
925 }
926
927 #define get_button_iface(u) _get_button_iface(__LINE__,u)
928 static IHTMLButtonElement *_get_button_iface(unsigned line, IUnknown *unk)
929 {
930 IHTMLButtonElement *ret;
931 HRESULT hres;
932
933 hres = IUnknown_QueryInterface(unk, &IID_IHTMLButtonElement, (void**)&ret);
934 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLButtonElement: %08x\n", hres);
935 return ret;
936 }
937
938 #define get_label_iface(u) _get_label_iface(__LINE__,u)
939 static IHTMLLabelElement *_get_label_iface(unsigned line, IUnknown *unk)
940 {
941 IHTMLLabelElement *ret;
942 HRESULT hres;
943
944 hres = IUnknown_QueryInterface(unk, &IID_IHTMLLabelElement, (void**)&ret);
945 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLabelElement: %08x\n", hres);
946 return ret;
947 }
948
949 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
950 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
951 {
952 IHTMLDOMNode *node = _get_node_iface(line, unk);
953 BSTR name;
954 HRESULT hres;
955
956 hres = IHTMLDOMNode_get_nodeName(node, &name);
957 IHTMLDOMNode_Release(node);
958 ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres);
959 ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname);
960
961 SysFreeString(name);
962 }
963
964 #define get_owner_doc(u) _get_owner_doc(__LINE__,u)
965 static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
966 {
967 IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
968 IDispatch *disp = (void*)0xdeadbeef;
969 IHTMLDocument2 *doc = NULL;
970 HRESULT hres;
971
972 hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
973 IHTMLDOMNode2_Release(node);
974 ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
975
976 if(disp) {
977 hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
978 IDispatch_Release(disp);
979 ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
980 }
981
982 return doc;
983 }
984
985 #define get_doc_window(d) _get_doc_window(__LINE__,d)
986 static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
987 {
988 IHTMLWindow2 *window;
989 HRESULT hres;
990
991 window = NULL;
992 hres = IHTMLDocument2_get_parentWindow(doc, &window);
993 ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
994 ok_(__FILE__,line)(window != NULL, "window == NULL\n");
995
996 return window;
997 }
998
999 #define clone_node(n,d) _clone_node(__LINE__,n,d)
1000 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
1001 {
1002 IHTMLDOMNode *node = _get_node_iface(line, unk);
1003 IHTMLDOMNode *ret = NULL;
1004 HRESULT hres;
1005
1006 hres = IHTMLDOMNode_cloneNode(node, deep, &ret);
1007 IHTMLDOMNode_Release(node);
1008 ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres);
1009 ok_(__FILE__,line)(ret != NULL, "ret == NULL\n");
1010
1011 return ret;
1012
1013 }
1014
1015 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
1016 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
1017 {
1018 IHTMLElement *elem = _get_elem_iface(line, unk);
1019 BSTR tag;
1020 HRESULT hres;
1021
1022 hres = IHTMLElement_get_tagName(elem, &tag);
1023 IHTMLElement_Release(elem);
1024 ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
1025 ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
1026
1027 SysFreeString(tag);
1028 }
1029
1030 #define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t)
1031 static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type)
1032 {
1033 _test_elem_tag(line, unk, elem_type_infos[type].tag);
1034 _test_ifaces(line, unk, elem_type_infos[type].iids);
1035
1036 if(elem_type_infos[type].dispiid && type != ET_A)
1037 _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]");
1038 }
1039
1040 #define get_node_type(n) _get_node_type(__LINE__,n)
1041 static LONG _get_node_type(unsigned line, IUnknown *unk)
1042 {
1043 IHTMLDOMNode *node = _get_node_iface(line, unk);
1044 LONG type = -1;
1045 HRESULT hres;
1046
1047 hres = IHTMLDOMNode_get_nodeType(node, &type);
1048 ok(hres == S_OK, "get_nodeType failed: %08x\n", hres);
1049
1050 IHTMLDOMNode_Release(node);
1051
1052 return type;
1053 }
1054
1055 #define get_child_nodes(u) _get_child_nodes(__LINE__,u)
1056 static IHTMLDOMChildrenCollection *_get_child_nodes(unsigned line, IUnknown *unk)
1057 {
1058 IHTMLDOMNode *node = _get_node_iface(line, unk);
1059 IHTMLDOMChildrenCollection *col = NULL;
1060 IDispatch *disp;
1061 HRESULT hres;
1062
1063 hres = IHTMLDOMNode_get_childNodes(node, &disp);
1064 IHTMLDOMNode_Release(node);
1065 ok_(__FILE__,line) (hres == S_OK, "get_childNodes failed: %08x\n", hres);
1066 if(FAILED(hres))
1067 return NULL;
1068
1069 hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMChildrenCollection, (void**)&col);
1070 IDispatch_Release(disp);
1071 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMChildrenCollection: %08x\n", hres);
1072
1073 return col;
1074 }
1075
1076 #define get_child_item(c,i) _get_child_item(__LINE__,c,i)
1077 static IHTMLDOMNode *_get_child_item(unsigned line, IHTMLDOMChildrenCollection *col, LONG idx)
1078 {
1079 IHTMLDOMNode *node = NULL;
1080 IDispatch *disp;
1081 HRESULT hres;
1082
1083 hres = IHTMLDOMChildrenCollection_item(col, idx, &disp);
1084 ok(hres == S_OK, "item failed: %08x\n", hres);
1085
1086 node = _get_node_iface(line, (IUnknown*)disp);
1087 IDispatch_Release(disp);
1088
1089 return node;
1090 }
1091
1092 #define test_elem_attr(e,n,v) _test_elem_attr(__LINE__,e,n,v)
1093 static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, const char *exval)
1094 {
1095 VARIANT value;
1096 BSTR tmp;
1097 HRESULT hres;
1098
1099 VariantInit(&value);
1100
1101 tmp = a2bstr(name);
1102 hres = IHTMLElement_getAttribute(elem, tmp, 0, &value);
1103 SysFreeString(tmp);
1104 ok_(__FILE__,line) (hres == S_OK, "getAttribute failed: %08x\n", hres);
1105
1106 if(exval) {
1107 ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value));
1108 ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value)));
1109 }else {
1110 ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value));
1111 }
1112
1113 VariantClear(&value);
1114 }
1115
1116 #define test_elem_offset(a,b) _test_elem_offset(__LINE__,a,b)
1117 static void _test_elem_offset(unsigned line, IUnknown *unk, const char *parent_tag)
1118 {
1119 IHTMLElement *elem = _get_elem_iface(line, unk);
1120 IHTMLElement *off_parent;
1121 LONG l;
1122 HRESULT hres;
1123
1124 hres = IHTMLElement_get_offsetTop(elem, &l);
1125 ok_(__FILE__,line) (hres == S_OK, "get_offsetTop failed: %08x\n", hres);
1126
1127 hres = IHTMLElement_get_offsetHeight(elem, &l);
1128 ok_(__FILE__,line) (hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
1129
1130 hres = IHTMLElement_get_offsetWidth(elem, &l);
1131 ok_(__FILE__,line) (hres == S_OK, "get_offsetWidth failed: %08x\n", hres);
1132
1133 hres = IHTMLElement_get_offsetLeft(elem, &l);
1134 ok_(__FILE__,line) (hres == S_OK, "get_offsetLeft failed: %08x\n", hres);
1135
1136 hres = IHTMLElement_get_offsetParent(elem, &off_parent);
1137 ok_(__FILE__,line) (hres == S_OK, "get_offsetParent failed: %08x\n", hres);
1138
1139 _test_elem_tag(line, (IUnknown*)off_parent, parent_tag);
1140 IHTMLElement_Release(off_parent);
1141
1142 IHTMLElement_Release(elem);
1143 }
1144
1145 #define test_elem_source_index(a,b) _test_elem_source_index(__LINE__,a,b)
1146 static void _test_elem_source_index(unsigned line, IHTMLElement *elem, int index)
1147 {
1148 LONG l = 0xdeadbeef;
1149 HRESULT hres;
1150
1151 hres = IHTMLElement_get_sourceIndex(elem, &l);
1152 ok_(__FILE__,line)(hres == S_OK, "get_sourceIndex failed: %08x\n", hres);
1153 ok_(__FILE__,line)(l == index, "sourceIndex = %d, expected %d\n", l, index);
1154 }
1155
1156 #define get_doc_node(d) _get_doc_node(__LINE__,d)
1157 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
1158 {
1159 IHTMLWindow2 *window;
1160 IHTMLDocument2 *ret;
1161 HRESULT hres;
1162
1163 hres = IHTMLDocument2_get_parentWindow(doc, &window);
1164 ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1165
1166 hres = IHTMLWindow2_get_document(window, &ret);
1167 ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres);
1168 ok_(__FILE__,line)(ret != NULL, "document = NULL\n");
1169
1170 return ret;
1171 }
1172
1173 #define test_window_name(d,e) _test_window_name(__LINE__,d,e)
1174 static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
1175 {
1176 BSTR name;
1177 HRESULT hres;
1178
1179 hres = IHTMLWindow2_get_name(window, &name);
1180 ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1181 if(exname)
1182 ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
1183 else
1184 ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
1185 SysFreeString(name);
1186 }
1187
1188 #define set_window_name(w,n) _set_window_name(__LINE__,w,n)
1189 static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
1190 {
1191 BSTR str;
1192 HRESULT hres;
1193
1194 str = a2bstr(name);
1195 hres = IHTMLWindow2_put_name(window, str);
1196 SysFreeString(str);
1197 ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1198
1199 _test_window_name(line, window, name);
1200 }
1201
1202 #define test_window_status(d) _test_window_status(__LINE__,d)
1203 static void _test_window_status(unsigned line, IHTMLWindow2 *window)
1204 {
1205 BSTR status;
1206 HRESULT hres;
1207
1208 status = (void*)0xdeadbeef;
1209 hres = IHTMLWindow2_get_status(window, &status);
1210 ok_(__FILE__,line)(hres == S_OK, "get_status failed: %08x\n", hres);
1211 ok_(__FILE__,line)(!status, "status = %s\n", wine_dbgstr_w(status));
1212 SysFreeString(status);
1213 }
1214
1215 #define set_window_status(w,n) _set_window_status(__LINE__,w,n)
1216 static void _set_window_status(unsigned line, IHTMLWindow2 *window, const char *status)
1217 {
1218 BSTR str;
1219 HRESULT hres;
1220
1221 str = a2bstr(status);
1222 hres = IHTMLWindow2_put_status(window, str);
1223 SysFreeString(str);
1224 ok_(__FILE__,line)(hres == S_OK, "put_status failed: %08x\n", hres);
1225 }
1226
1227 #define test_window_length(w,l) _test_window_length(__LINE__,w,l)
1228 static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
1229 {
1230 LONG length = -1;
1231 HRESULT hres;
1232
1233 hres = IHTMLWindow2_get_length(window, &length);
1234 ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
1235 ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
1236 }
1237
1238 #define get_frame_content_window(e) _get_frame_content_window(__LINE__,e)
1239 static IHTMLWindow2 *_get_frame_content_window(unsigned line, IUnknown *elem)
1240 {
1241 IHTMLFrameBase2 *base2;
1242 IHTMLWindow2 *window;
1243 HRESULT hres;
1244
1245 hres = IUnknown_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
1246 ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
1247
1248 window = NULL;
1249 hres = IHTMLFrameBase2_get_contentWindow(base2, &window);
1250 IHTMLFrameBase2_Release(base2);
1251 ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
1252 ok(window != NULL, "contentWindow = NULL\n");
1253
1254 return window;
1255 }
1256
1257 static void test_get_set_attr(IHTMLDocument2 *doc)
1258 {
1259 IHTMLElement *elem;
1260 IHTMLDocument3 *doc3;
1261 HRESULT hres;
1262 BSTR bstr;
1263 VARIANT val;
1264
1265 /* grab an element to test with */
1266 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1267 ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
1268
1269 hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1270 IHTMLDocument3_Release(doc3);
1271 ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
1272
1273 /* get a non-present attribute */
1274 bstr = a2bstr("notAnAttribute");
1275 hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1276 ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1277 ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val));
1278 VariantClear(&val);
1279 SysFreeString(bstr);
1280
1281 /* get a present attribute */
1282 bstr = a2bstr("scrollHeight");
1283 hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1284 ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1285 ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val));
1286 VariantClear(&val);
1287 SysFreeString(bstr);
1288
1289 /* create a new BSTR attribute */
1290 bstr = a2bstr("newAttribute");
1291
1292 V_VT(&val) = VT_BSTR;
1293 V_BSTR(&val) = a2bstr("the value");
1294 hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1295 ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1296 VariantClear(&val);
1297
1298 hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1299 ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1300 ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val));
1301 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)));
1302 VariantClear(&val);
1303
1304 /* overwrite the attribute with a BOOL */
1305 V_VT(&val) = VT_BOOL;
1306 V_BOOL(&val) = VARIANT_TRUE;
1307 hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1308 ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1309 VariantClear(&val);
1310
1311 hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1312 ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1313 ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1314 ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1315 VariantClear(&val);
1316
1317 SysFreeString(bstr);
1318
1319 /* case-insensitive */
1320 bstr = a2bstr("newattribute");
1321 hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1322 ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1323 ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1324 ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1325 VariantClear(&val);
1326 SysFreeString(bstr);
1327
1328 IHTMLElement_Release(elem);
1329 }
1330
1331 #define get_doc_elem(d) _get_doc_elem(__LINE__,d)
1332 static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc)
1333 {
1334 IHTMLElement *elem;
1335 IHTMLDocument3 *doc3;
1336 HRESULT hres;
1337
1338 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1339 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
1340 hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1341 ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres);
1342 IHTMLDocument3_Release(doc3);
1343
1344 return elem;
1345 }
1346
1347 #define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h)
1348 static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref)
1349 {
1350 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1351 BSTR str;
1352 HRESULT hres;
1353
1354 hres = IHTMLAnchorElement_get_href(anchor, &str);
1355 ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1356 ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref);
1357 SysFreeString(str);
1358
1359 _test_disp_value(line, unk, exhref);
1360 }
1361
1362 #define test_anchor_put_href(a,h) _test_anchor_put_href(__LINE__,a,h)
1363 static void _test_anchor_put_href(unsigned line, IUnknown *unk, const char *exhref)
1364 {
1365 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1366 BSTR str;
1367 HRESULT hres;
1368
1369 str = a2bstr(exhref);
1370 hres = IHTMLAnchorElement_put_href(anchor, str);
1371 ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1372 SysFreeString(str);
1373
1374 _test_disp_value(line, unk, exhref);
1375 }
1376
1377 #define test_anchor_rel(a,h) _test_anchor_rel(__LINE__,a,h)
1378 static void _test_anchor_rel(unsigned line, IUnknown *unk, const char *exrel)
1379 {
1380 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1381 BSTR str;
1382 HRESULT hres;
1383
1384 hres = IHTMLAnchorElement_get_rel(anchor, &str);
1385 ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
1386 if(exrel)
1387 ok_(__FILE__,line)(!strcmp_wa(str, exrel), "rel = %s, expected %s\n", wine_dbgstr_w(str), exrel);
1388 else
1389 ok_(__FILE__,line)(!str, "rel = %s, expected NULL\n", wine_dbgstr_w(str));
1390 SysFreeString(str);
1391 }
1392
1393 #define test_anchor_put_rel(a,h) _test_anchor_put_rel(__LINE__,a,h)
1394 static void _test_anchor_put_rel(unsigned line, IUnknown *unk, const char *exrel)
1395 {
1396 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1397 BSTR str;
1398 HRESULT hres;
1399
1400 str = a2bstr(exrel);
1401 hres = IHTMLAnchorElement_put_rel(anchor, str);
1402 ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
1403 SysFreeString(str);
1404 }
1405
1406 #define test_anchor_get_target(a,h) _test_anchor_get_target(__LINE__,a,h)
1407 static void _test_anchor_get_target(unsigned line, IUnknown *unk, const char *target)
1408 {
1409 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1410 BSTR str;
1411 HRESULT hres;
1412
1413 hres = IHTMLAnchorElement_get_target(anchor, &str);
1414 ok_(__FILE__,line)(hres == S_OK, "get_target failed: %08x\n", hres);
1415 if(target)
1416 ok_(__FILE__,line)(!strcmp_wa(str, target), "target = %s, expected %s\n", wine_dbgstr_w(str), target);
1417 else
1418 ok_(__FILE__,line)(str == NULL, "target = %s, expected NULL\n", wine_dbgstr_w(str));
1419 SysFreeString(str);
1420 }
1421
1422 #define test_anchor_put_target(a,h) _test_anchor_put_target(__LINE__,a,h)
1423 static void _test_anchor_put_target(unsigned line, IUnknown *unk, const char *target)
1424 {
1425 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1426 BSTR str;
1427 HRESULT hres;
1428
1429 str = target ? a2bstr(target) : NULL;
1430 hres = IHTMLAnchorElement_put_target(anchor, str);
1431 ok_(__FILE__,line)(hres == S_OK, "put_target failed: %08x\n", hres);
1432 SysFreeString(str);
1433 }
1434
1435 #define test_anchor_name(a,h) _test_anchor_name(__LINE__,a,h)
1436 static void _test_anchor_name(unsigned line, IUnknown *unk, const char *name)
1437 {
1438 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1439 BSTR str;
1440 HRESULT hres;
1441
1442 hres = IHTMLAnchorElement_get_name(anchor, &str);
1443 ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1444 if(name)
1445 ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
1446 else
1447 ok_(__FILE__,line)(str == NULL, "name = %s, expected NULL\n", wine_dbgstr_w(str));
1448 SysFreeString(str);
1449 }
1450
1451 #define test_anchor_put_name(a,h) _test_anchor_put_name(__LINE__,a,h)
1452 static void _test_anchor_put_name(unsigned line, IUnknown *unk, const char *name)
1453 {
1454 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1455 BSTR str;
1456 HRESULT hres;
1457
1458 str = name ? a2bstr(name) : NULL;
1459 hres = IHTMLAnchorElement_put_name(anchor, str);
1460 ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1461 SysFreeString(str);
1462
1463 _test_anchor_name(line, unk, name);
1464 }
1465
1466 #define test_anchor_hostname(a,h) _test_anchor_hostname(__LINE__,a,h)
1467 static void _test_anchor_hostname(unsigned line, IUnknown *unk, const char *hostname)
1468 {
1469 IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1470 BSTR str;
1471 HRESULT hres;
1472
1473 hres = IHTMLAnchorElement_get_hostname(anchor, &str);
1474 ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1475 if(hostname)
1476 ok_(__FILE__,line)(!strcmp_wa(str, hostname), "hostname = %s, expected %s\n", wine_dbgstr_w(str), hostname);
1477 else
1478 ok_(__FILE__,line)(str == NULL, "hostname = %s, expected NULL\n", wine_dbgstr_w(str));
1479 SysFreeString(str);
1480 }
1481
1482 #define test_anchor_hash(a,h) _test_anchor_hash(__LINE__,a,h)
1483 static void _test_anchor_hash(unsigned line, IHTMLElement *elem, const char *exhash)
1484 {
1485 IHTMLAnchorElement *anchor = _get_anchor_iface(line, (IUnknown*)elem);
1486 BSTR str;
1487 HRESULT hres;
1488
1489 hres = IHTMLAnchorElement_get_hash(anchor, &str);
1490 ok_(__FILE__,line)(hres == S_OK, "get_hash failed: %08x\n", hres);
1491 if(exhash)
1492 ok_(__FILE__,line)(!strcmp_wa(str, exhash), "hash = %s, expected %s\n", wine_dbgstr_w(str), exhash);
1493 else
1494 ok_(__FILE__,line)(!str, "hash = %s, expected NULL\n", wine_dbgstr_w(str));
1495 SysFreeString(str);
1496 }
1497
1498 #define test_option_text(o,t) _test_option_text(__LINE__,o,t)
1499 static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text)
1500 {
1501 BSTR bstr;
1502 HRESULT hres;
1503
1504 hres = IHTMLOptionElement_get_text(option, &bstr);
1505 ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres);
1506 ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr));
1507 SysFreeString(bstr);
1508 }
1509
1510 #define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t)
1511 static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text)
1512 {
1513 BSTR bstr;
1514 HRESULT hres;
1515
1516 bstr = a2bstr(text);
1517 hres = IHTMLOptionElement_put_text(option, bstr);
1518 SysFreeString(bstr);
1519 ok(hres == S_OK, "put_text failed: %08x\n", hres);
1520
1521 _test_option_text(line, option, text);
1522 }
1523
1524 #define test_option_value(o,t) _test_option_value(__LINE__,o,t)
1525 static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value)
1526 {
1527 BSTR bstr;
1528 HRESULT hres;
1529
1530 hres = IHTMLOptionElement_get_value(option, &bstr);
1531 ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1532 ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr));
1533 SysFreeString(bstr);
1534 }
1535
1536 #define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t)
1537 static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value)
1538 {
1539 BSTR bstr;
1540 HRESULT hres;
1541
1542 bstr = a2bstr(value);
1543 hres = IHTMLOptionElement_put_value(option, bstr);
1544 SysFreeString(bstr);
1545 ok(hres == S_OK, "put_value failed: %08x\n", hres);
1546
1547 _test_option_value(line, option, value);
1548 }
1549
1550 #define test_option_selected(o,s) _test_option_selected(__LINE__,o,s)
1551 static void _test_option_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex)
1552 {
1553 VARIANT_BOOL b = 0x100;
1554 HRESULT hres;
1555
1556 hres = IHTMLOptionElement_get_selected(option, &b);
1557 ok_(__FILE__,line)(hres == S_OK, "get_selected failed: %08x\n", hres);
1558 ok_(__FILE__,line)(b == ex, "selected = %x, expected %x\n", b, ex);
1559 }
1560
1561 #define test_option_put_selected(o,s) _test_option_put_selected(__LINE__,o,s)
1562 static void _test_option_put_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b)
1563 {
1564 HRESULT hres;
1565
1566 hres = IHTMLOptionElement_put_selected(option, b);
1567 ok_(__FILE__,line)(hres == S_OK, "put_selected failed: %08x\n", hres);
1568 _test_option_selected(line, option, b);
1569 }
1570
1571 #define test_textarea_value(t,v) _test_textarea_value(__LINE__,t,v)
1572 static void _test_textarea_value(unsigned line, IUnknown *unk, const char *exval)
1573 {
1574 IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1575 BSTR value = (void*)0xdeadbeef;
1576 HRESULT hres;
1577
1578 hres = IHTMLTextAreaElement_get_value(textarea, &value);
1579 IHTMLTextAreaElement_Release(textarea);
1580 ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres);
1581 if(exval)
1582 ok_(__FILE__,line)(!strcmp_wa(value, exval), "value = %s, expected %s\n", wine_dbgstr_w(value), exval);
1583 else
1584 ok_(__FILE__,line)(!value, "value = %p\n", value);
1585 SysFreeString(value);
1586 }
1587
1588 #define test_textarea_put_value(t,v) _test_textarea_put_value(__LINE__,t,v)
1589 static void _test_textarea_put_value(unsigned line, IUnknown *unk, const char *value)
1590 {
1591 IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1592 BSTR tmp = a2bstr(value);
1593 HRESULT hres;
1594
1595 hres = IHTMLTextAreaElement_put_value(textarea, tmp);
1596 IHTMLTextAreaElement_Release(textarea);
1597 ok_(__FILE__,line)(hres == S_OK, "put_value failed: %08x\n", hres);
1598 SysFreeString(tmp);
1599
1600 _test_textarea_value(line, unk, value);
1601 }
1602
1603 #define test_textarea_readonly(t,v) _test_textarea_readonly(__LINE__,t,v)
1604 static void _test_textarea_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL ex)
1605 {
1606 IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1607 VARIANT_BOOL b = 0x100;
1608 HRESULT hres;
1609
1610 hres = IHTMLTextAreaElement_get_readOnly(textarea, &b);
1611 IHTMLTextAreaElement_Release(textarea);
1612 ok_(__FILE__,line)(hres == S_OK, "get_readOnly failed: %08x\n", hres);
1613 ok_(__FILE__,line)(b == ex, "readOnly = %x, expected %x\n", b, ex);
1614 }
1615
1616 #define test_textarea_put_readonly(t,v) _test_textarea_put_readonly(__LINE__,t,v)
1617 static void _test_textarea_put_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL b)
1618 {
1619 IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1620 HRESULT hres;
1621
1622 hres = IHTMLTextAreaElement_put_readOnly(textarea, b);
1623 IHTMLTextAreaElement_Release(textarea);
1624 ok_(__FILE__,line)(hres == S_OK, "put_readOnly failed: %08x\n", hres);
1625
1626 _test_textarea_readonly(line, unk, b);
1627 }
1628
1629 #define test_textarea_type(t) _test_textarea_type(__LINE__,t)
1630 static void _test_textarea_type(unsigned line, IUnknown *unk)
1631 {
1632 IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1633 BSTR type = (void*)0xdeadbeef;
1634 HRESULT hres;
1635
1636 hres = IHTMLTextAreaElement_get_type(textarea, &type);
1637 IHTMLTextAreaElement_Release(textarea);
1638 ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
1639 ok_(__FILE__,line)(!strcmp_wa(type, "textarea"), "type = %s, expected textarea\n", wine_dbgstr_w(type));
1640 SysFreeString(type);
1641 }
1642
1643 #define test_comment_text(c,t) _test_comment_text(__LINE__,c,t)
1644 static void _test_comment_text(unsigned line, IUnknown *unk, const char *extext)
1645 {
1646 IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1647 BSTR text;
1648 HRESULT hres;
1649
1650 text = a2bstr(extext);
1651 hres = IHTMLCommentElement_get_text(comment, &text);
1652 ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
1653 ok_(__FILE__,line)(!strcmp_wa(text, extext), "text = \"%s\", expected \"%s\"\n", wine_dbgstr_w(text), extext);
1654
1655 IHTMLCommentElement_Release(comment);
1656 SysFreeString(text);
1657 }
1658
1659 #define test_comment_attrs(c) _test_comment_attrs(__LINE__,c)
1660 static void _test_comment_attrs(unsigned line, IUnknown *unk)
1661 {
1662 IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1663 IHTMLElement *elem = _get_elem_iface(__LINE__,unk);
1664 IHTMLElement4 *elem4 = _get_elem4_iface(__LINE__,unk);
1665 IHTMLDOMAttribute *attr;
1666 BSTR name = a2bstr("test");
1667 VARIANT val;
1668 HRESULT hres;
1669
1670 hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1671 ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1672 ok(attr == NULL, "attr != NULL\n");
1673
1674 V_VT(&val) = VT_I4;
1675 V_I4(&val) = 1234;
1676 hres = IHTMLElement_setAttribute(elem, name, val, 0);
1677 ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1678
1679 hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1680 ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1681 ok(attr != NULL, "attr == NULL\n");
1682
1683 IHTMLDOMAttribute_Release(attr);
1684 IHTMLCommentElement_Release(comment);
1685 IHTMLElement_Release(elem);
1686 IHTMLElement4_Release(elem4);
1687 SysFreeString(name);
1688 }
1689
1690 #define test_object_vspace(u,s) _test_object_vspace(__LINE__,u,s)
1691 static void _test_object_vspace(unsigned line, IUnknown *unk, LONG exl)
1692 {
1693 IHTMLObjectElement *object = _get_object_iface(line, unk);
1694 LONG l;
1695 HRESULT hres;
1696
1697 l = 0xdeadbeef;
1698 hres = IHTMLObjectElement_get_vspace(object, &l);
1699 ok_(__FILE__,line)(hres == S_OK, "get_vspace failed: %08x\n", hres);
1700 ok_(__FILE__,line)(l == exl, "vspace=%d, expected %d\n", l, exl);
1701 IHTMLObjectElement_Release(object);
1702 }
1703
1704 #define test_object_name(a,b) _test_object_name(__LINE__,a,b)
1705 static void _test_object_name(unsigned line, IHTMLElement *elem, const char *exname)
1706 {
1707 IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1708 BSTR str;
1709 HRESULT hres;
1710
1711 str = (void*)0xdeadbeef;
1712 hres = IHTMLObjectElement_get_name(object, &str);
1713 ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1714 if(exname)
1715 ok_(__FILE__,line)(!strcmp_wa(str, exname), "name=%s, expected %s\n", wine_dbgstr_w(str), exname);
1716 else
1717 ok_(__FILE__,line)(!str, "name=%s, expected NULL\n", wine_dbgstr_w(str));
1718 SysFreeString(str);
1719 IHTMLObjectElement_Release(object);
1720 }
1721
1722 #define set_object_name(a,b) _set_object_name(__LINE__,a,b)
1723 static void _set_object_name(unsigned line, IHTMLElement *elem, const char *name)
1724 {
1725 IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1726 BSTR str;
1727 HRESULT hres;
1728
1729 str = a2bstr(name);
1730 hres = IHTMLObjectElement_put_name(object, str);
1731 ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1732 SysFreeString(str);
1733 IHTMLObjectElement_Release(object);
1734
1735 _test_object_name(line, elem, name);
1736 }
1737
1738 #define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v)
1739 static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc,
1740 const char *txt, const char *val)
1741 {
1742 IHTMLOptionElementFactory *factory;
1743 IHTMLOptionElement *option;
1744 IHTMLWindow2 *window;
1745 VARIANT text, value, empty;
1746 HRESULT hres;
1747
1748 hres = IHTMLDocument2_get_parentWindow(doc, &window);
1749 ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1750
1751 hres = IHTMLWindow2_get_Option(window, &factory);
1752 IHTMLWindow2_Release(window);
1753 ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres);
1754
1755 test_disp((IUnknown*)factory, &IID_IHTMLOptionElementFactory, "[object]");
1756
1757 V_VT(&text) = VT_BSTR;
1758 V_BSTR(&text) = a2bstr(txt);
1759 V_VT(&value) = VT_BSTR;
1760 V_BSTR(&value) = a2bstr(val);
1761 V_VT(&empty) = VT_EMPTY;
1762
1763 hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option);
1764 ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1765
1766 IHTMLOptionElementFactory_Release(factory);
1767 VariantClear(&text);
1768 VariantClear(&value);
1769
1770 _test_option_text(line, option, txt);
1771 _test_option_value(line, option, val);
1772 _test_option_selected(line, option, VARIANT_FALSE);
1773
1774 return option;
1775 }
1776
1777 #define test_img_width(o,w) _test_img_width(__LINE__,o,w)
1778 static void _test_img_width(unsigned line, IHTMLImgElement *img, const LONG exp)
1779 {
1780 LONG found = -1;
1781 HRESULT hres;
1782
1783 hres = IHTMLImgElement_get_width(img, &found);
1784 ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
1785 ok_(__FILE__,line) (found == exp, "width=%d\n", found);
1786 }
1787
1788 #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
1789 static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const LONG width)
1790 {
1791 HRESULT hres;
1792
1793 hres = IHTMLImgElement_put_width(img, width);
1794 ok(hres == S_OK, "put_width failed: %08x\n", hres);
1795
1796 _test_img_width(line, img, width);
1797 }
1798
1799 #define test_img_height(o,h) _test_img_height(__LINE__,o,h)
1800 static void _test_img_height(unsigned line, IHTMLImgElement *img, const LONG exp)
1801 {
1802 LONG found = -1;
1803 HRESULT hres;
1804
1805 hres = IHTMLImgElement_get_height(img, &found);
1806 ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
1807 ok_(__FILE__,line) (found == exp, "height=%d\n", found);
1808 }
1809
1810 #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
1811 static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const LONG height)
1812 {
1813 HRESULT hres;
1814
1815 hres = IHTMLImgElement_put_height(img, height);
1816 ok(hres == S_OK, "put_height failed: %08x\n", hres);
1817
1818 _test_img_height(line, img, height);
1819 }
1820
1821 #define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
1822 static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
1823 LONG wdth, LONG hght)
1824 {
1825 IHTMLImageElementFactory *factory;
1826 IHTMLImgElement *img;
1827 IHTMLWindow2 *window;
1828 VARIANT width, height;
1829 char buf[16];
1830 HRESULT hres;
1831
1832 hres = IHTMLDocument2_get_parentWindow(doc, &window);
1833 ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1834
1835 hres = IHTMLWindow2_get_Image(window, &factory);
1836 IHTMLWindow2_Release(window);
1837 ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
1838
1839 test_ifaces((IUnknown*)factory, img_factory_iids);
1840 test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
1841
1842 if(wdth >= 0){
1843 snprintf(buf, 16, "%d", wdth);
1844 V_VT(&width) = VT_BSTR;
1845 V_BSTR(&width) = a2bstr(buf);
1846 }else{
1847 V_VT(&width) = VT_EMPTY;
1848 wdth = 0;
1849 }
1850
1851 if(hght >= 0){
1852 snprintf(buf, 16, "%d", hght);
1853 V_VT(&height) = VT_BSTR;
1854 V_BSTR(&height) = a2bstr(buf);
1855 }else{
1856 V_VT(&height) = VT_EMPTY;
1857 hght = 0;
1858 }
1859
1860 hres = IHTMLImageElementFactory_create(factory, width, height, &img);
1861 ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1862
1863 IHTMLImageElementFactory_Release(factory);
1864 VariantClear(&width);
1865 VariantClear(&height);
1866
1867 if(SUCCEEDED(hres)) {
1868 _test_img_width(line, img, wdth);
1869 _test_img_height(line, img, hght);
1870 return img;
1871 }
1872
1873 return NULL;
1874 }
1875
1876 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
1877 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
1878 {
1879 LONG len = 0xdeadbeef;
1880 HRESULT hres;
1881
1882 hres = IHTMLSelectElement_get_length(select, &len);
1883 ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1884 ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length);
1885 }
1886
1887 #define test_select_put_length(s,l) _test_select_put_length(__LINE__,s,l)
1888 static void _test_select_put_length(unsigned line, IUnknown *unk, LONG length)
1889 {
1890 IHTMLSelectElement *select = _get_select_iface(line, unk);
1891 HRESULT hres;
1892
1893 hres = IHTMLSelectElement_put_length(select, length);
1894 ok_(__FILE__,line) (hres == S_OK, "put_length failed: %08x\n", hres);
1895 _test_select_length(line, select, length);
1896 IHTMLSelectElement_Release(select);
1897 }
1898
1899 #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i)
1900 static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1901 {
1902 LONG idx = 0xdeadbeef;
1903 HRESULT hres;
1904
1905 hres = IHTMLSelectElement_get_selectedIndex(select, &idx);
1906 ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1907 ok_(__FILE__,line) (idx == index, "idx=%d, expected %d\n", idx, index);
1908 }
1909
1910 #define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i)
1911 static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1912 {
1913 HRESULT hres;
1914
1915 hres = IHTMLSelectElement_put_selectedIndex(select, index);
1916 ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1917 _test_select_selidx(line, select, index);
1918 }
1919
1920 #define test_select_value(s,v) _test_select_value(__LINE__,s,v)
1921 static void _test_select_value(unsigned line, IHTMLSelectElement *select, const char *exval)
1922 {
1923 BSTR val;
1924 HRESULT hres;
1925
1926 hres = IHTMLSelectElement_get_value(select, &val);
1927 ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1928 if(exval)
1929 ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val));
1930 else
1931 ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val));
1932 SysFreeString(val);
1933 }
1934
1935 #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v)
1936 static void _test_select_set_value(unsigned line, IHTMLSelectElement *select, const char *val)
1937 {
1938 BSTR bstr;
1939 HRESULT hres;
1940
1941 bstr = a2bstr(val);
1942 hres = IHTMLSelectElement_put_value(select, bstr);
1943 SysFreeString(bstr);
1944 ok_(__FILE__,line) (hres == S_OK, "put_value failed: %08x\n", hres);
1945 }
1946
1947 #define test_select_type(s,t) _test_select_type(__LINE__,s,t)
1948 static void _test_select_type(unsigned line, IHTMLSelectElement *select, const char *extype)
1949 {
1950 BSTR type;
1951 HRESULT hres;
1952
1953 hres = IHTMLSelectElement_get_type(select, &type);
1954 ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
1955 ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
1956 SysFreeString(type);
1957 }
1958
1959 #define test_select_multiple(s,t) _test_select_multiple(__LINE__,s,t)
1960 static void _test_select_multiple(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exmultiple)
1961 {
1962 VARIANT_BOOL b = 100;
1963 HRESULT hres;
1964
1965 hres = IHTMLSelectElement_get_multiple(select, &b);
1966 ok_(__FILE__,line) (hres == S_OK, "get_multiple failed: %08x\n", hres);
1967 ok_(__FILE__,line) (b == exmultiple, "multiple=%x, expected %x\n", b, exmultiple);
1968 }
1969
1970 #define test_select_set_multiple(s,v) _test_select_set_multiple(__LINE__,s,v)
1971 static void _test_select_set_multiple(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL val)
1972 {
1973 HRESULT hres;
1974
1975 hres = IHTMLSelectElement_put_multiple(select, val);
1976 ok_(__FILE__,line) (hres == S_OK, "put_multiple failed: %08x\n", hres);
1977
1978 _test_select_multiple(line, select, val);
1979 }
1980
1981 #define test_range_text(r,t) _test_range_text(__LINE__,r,t)
1982 static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext)
1983 {
1984 BSTR text;
1985 HRESULT hres;
1986
1987 hres = IHTMLTxtRange_get_text(range, &text);
1988 ok_(__FILE__, line) (hres == S_OK, "get_text failed: %08x\n", hres);
1989
1990 if(extext) {
1991 ok_(__FILE__, line) (text != NULL, "text == NULL\n");
1992 ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext);
1993 }else {
1994 ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text));
1995 }
1996
1997 SysFreeString(text);
1998
1999 }
2000
2001 #define test_range_collapse(r,b) _test_range_collapse(__LINE__,r,b)
2002 static void _test_range_collapse(unsigned line, IHTMLTxtRange *range, BOOL b)
2003 {
2004 HRESULT hres;
2005
2006 hres = IHTMLTxtRange_collapse(range, b);
2007 ok_(__FILE__, line) (hres == S_OK, "collapse failed: %08x\n", hres);
2008 _test_range_text(line, range, NULL);
2009 }
2010
2011 #define test_range_expand(r,u,b,t) _test_range_expand(__LINE__,r,u,b,t)
2012 static void _test_range_expand(unsigned line, IHTMLTxtRange *range, LPWSTR unit,
2013 VARIANT_BOOL exb, const char *extext)
2014 {
2015 VARIANT_BOOL b = 0xe0e0;
2016 HRESULT hres;
2017
2018 hres = IHTMLTxtRange_expand(range, unit, &b);
2019 ok_(__FILE__,line) (hres == S_OK, "expand failed: %08x\n", hres);
2020 ok_(__FILE__,line) (b == exb, "b=%x, expected %x\n", b, exb);
2021 _test_range_text(line, range, extext);
2022 }
2023
2024 #define test_range_move(r,u,c,e) _test_range_move(__LINE__,r,u,c,e)
2025 static void _test_range_move(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
2026 {
2027 LONG c = 0xdeadbeef;
2028 HRESULT hres;
2029
2030 hres = IHTMLTxtRange_move(range, unit, cnt, &c);
2031 ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
2032 ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
2033 _test_range_text(line, range, NULL);
2034 }
2035
2036 #define test_range_movestart(r,u,c,e) _test_range_movestart(__LINE__,r,u,c,e)
2037 static void _test_range_movestart(unsigned line, IHTMLTxtRange *range,
2038 LPWSTR unit, LONG cnt, LONG excnt)
2039 {
2040 LONG c = 0xdeadbeef;
2041 HRESULT hres;
2042
2043 hres = IHTMLTxtRange_moveStart(range, unit, cnt, &c);
2044 ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
2045 ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
2046 }
2047
2048 #define test_range_moveend(r,u,c,e) _test_range_moveend(__LINE__,r,u,c,e)
2049 static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
2050 {
2051 LONG c = 0xdeadbeef;
2052 HRESULT hres;
2053
2054 hres = IHTMLTxtRange_moveEnd(range, unit, cnt, &c);
2055 ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
2056 ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
2057 }
2058
2059 #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
2060 static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
2061 {
2062 HRESULT hres;
2063 BSTR bstr = a2bstr(text);
2064
2065 hres = IHTMLTxtRange_put_text(range, bstr);
2066 ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
2067 SysFreeString(bstr);
2068 _test_range_text(line, range, NULL);
2069 }
2070
2071 #define test_range_inrange(r1,r2,b) _test_range_inrange(__LINE__,r1,r2,b)
2072 static void _test_range_inrange(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
2073 {
2074 VARIANT_BOOL b;
2075 HRESULT hres;
2076
2077 b = 0xe0e0;
2078 hres = IHTMLTxtRange_inRange(range1, range2, &b);
2079 ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
2080 ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
2081 }
2082
2083 #define test_range_isequal(r1,r2,b) _test_range_isequal(__LINE__,r1,r2,b)
2084 static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
2085 {
2086 VARIANT_BOOL b;
2087 HRESULT hres;
2088
2089 b = 0xe0e0;
2090 hres = IHTMLTxtRange_isEqual(range1, range2, &b);
2091 ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
2092 ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
2093
2094 b = 0xe0e0;
2095 hres = IHTMLTxtRange_isEqual(range2, range1, &b);
2096 ok_(__FILE__,line) (hres == S_OK, "(2->1) isEqual failed: %08x\n", hres);
2097 ok_(__FILE__,line) (b == exb, "(2->1) b=%x, expected %x\n", b, exb);
2098
2099 if(exb) {
2100 test_range_inrange(range1, range2, VARIANT_TRUE);
2101 test_range_inrange(range2, range1, VARIANT_TRUE);
2102 }
2103 }
2104
2105 #define test_range_parent(r,t) _test_range_parent(__LINE__,r,t)
2106 static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t type)
2107 {
2108 IHTMLElement *elem;
2109 HRESULT hres;
2110
2111 hres = IHTMLTxtRange_parentElement(range, &elem);
2112 ok_(__FILE__,line) (hres == S_OK, "parentElement failed: %08x\n", hres);
2113
2114 _test_elem_type(line, (IUnknown*)elem, type);
2115
2116 IHTMLElement_Release(elem);
2117 }
2118
2119 #define get_elem_col_item_idx(a,b) _get_elem_col_item_idx(__LINE__,a,b)
2120 static IHTMLElement *_get_elem_col_item_idx(unsigned line, IHTMLElementCollection *col, int i)
2121 {
2122 VARIANT name, index;
2123 IHTMLElement *elem;
2124 IDispatch *disp;
2125 HRESULT hres;
2126
2127 V_VT(&index) = VT_EMPTY;
2128 V_VT(&name) = VT_I4;
2129 V_I4(&name) = i;
2130 hres = IHTMLElementCollection_item(col, name, index, &disp);
2131 ok_(__FILE__,line)(hres == S_OK, "item failed: %08x\n", hres);
2132 ok_(__FILE__,line)(disp != NULL, "disp == NULL\n");
2133
2134 elem = _get_elem_iface(line, (IUnknown*)disp);
2135 IDispatch_Release(disp);
2136 return elem;
2137 }
2138
2139 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
2140 static void _test_elem_collection(unsigned line, IUnknown *unk,
2141 const elem_type_t *elem_types, LONG exlen)
2142 {
2143 IHTMLElementCollection *col;
2144 IEnumVARIANT *enum_var;
2145 IUnknown *enum_unk;
2146 ULONG fetched;
2147 LONG len;
2148 DWORD i;
2149 VARIANT name, index, v, vs[5];
2150 IDispatch *disp, *disp2;
2151 HRESULT hres;
2152
2153 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col);
2154 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres);
2155
2156 test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]");
2157
2158 hres = IHTMLElementCollection_get_length(col, &len);
2159 ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
2160 ok_(__FILE__,line) (len == exlen, "len=%d, expected %d\n", len, exlen);
2161
2162 if(len > exlen)
2163 len = exlen;
2164
2165 V_VT(&index) = VT_EMPTY;
2166
2167 hres = IHTMLElementCollection_get__newEnum(col, &enum_unk);
2168 ok_(__FILE__,line)(hres == S_OK, "_newEnum failed: %08x\n", hres);
2169
2170 hres = IUnknown_QueryInterface(enum_unk, &IID_IEnumVARIANT, (void**)&enum_var);
2171 IUnknown_Release(enum_unk);
2172 ok_(__FILE__,line)(hres == S_OK, "Could not get IEnumVARIANT iface: %08x\n", hres);
2173
2174 for(i=0; i<len; i++) {
2175 V_VT(&name) = VT_I4;
2176 V_I4(&name) = i;
2177 disp = (void*)0xdeadbeef;
2178 hres = IHTMLElementCollection_item(col, name, index, &disp);
2179 ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2180 ok_(__FILE__,line) (disp != NULL, "item returned NULL\n");
2181 if(FAILED(hres) || !disp)
2182 continue;
2183
2184 _test_elem_type(line, (IUnknown*)disp, elem_types[i]);
2185
2186 if(!i) {
2187 V_VT(&name) = VT_UINT;
2188 V_I4(&name) = 0;
2189 disp2 = (void*)0xdeadbeef;
2190 hres = IHTMLElementCollection_item(col, name, index, &disp2);
2191 ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2192 ok_(__FILE__,line) (iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
2193 if(disp2)
2194 IDispatch_Release(disp2);
2195 }
2196
2197 fetched = 0;
2198 V_VT(&v) = VT_ERROR;
2199 hres = IEnumVARIANT_Next(enum_var, 1, &v, i ? &fetched : NULL);
2200 ok_(__FILE__,line)(hres == S_OK, "Next failed: %08x\n", hres);
2201 if(i)
2202 ok_(__FILE__,line)(fetched == 1, "fetched = %d\n", fetched);
2203 ok_(__FILE__,line)(V_VT(&v) == VT_DISPATCH && V_DISPATCH(&v), "V_VT(v) = %d\n", V_VT(&v));
2204 ok_(__FILE__,line)(iface_cmp((IUnknown*)disp, (IUnknown*)V_DISPATCH(&v)), "disp != V_DISPATCH(v)\n");
2205 IDispatch_Release(V_DISPATCH(&v));
2206
2207 IDispatch_Release(disp);
2208 }
2209
2210 fetched = 0xdeadbeef;
2211 V_VT(&v) = VT_BOOL;
2212 hres = IEnumVARIANT_Next(enum_var, 1, &v, &fetched);
2213 ok_(__FILE__,line)(hres == S_FALSE, "Next returned %08x, expected S_FALSE\n", hres);
2214 ok_(__FILE__,line)(fetched == 0, "fetched = %d\n", fetched);
2215 ok_(__FILE__,line)(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2216
2217 hres = IEnumVARIANT_Reset(enum_var);
2218 ok_(__FILE__,line)(hres == S_OK, "Reset failed: %08x\n", hres);
2219
2220 fetched = 0xdeadbeef;
2221 V_VT(&v) = VT_BOOL;
2222 hres = IEnumVARIANT_Next(enum_var, 0, &v, &fetched);
2223 ok_(__FILE__,line)(hres == S_OK, "Next returned %08x, expected S_FALSE\n", hres);
2224 ok_(__FILE__,line)(fetched == 0, "fetched = %d\n", fetched);
2225 ok_(__FILE__,line)(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2226
2227 hres = IEnumVARIANT_Skip(enum_var, len > 2 ? len-2 : 0);
2228 ok_(__FILE__,line)(hres == S_OK, "Skip failed: %08x\n", hres);
2229
2230 memset(vs, 0, sizeof(vs));
2231 fetched = 0;
2232 hres = IEnumVARIANT_Next(enum_var, sizeof(vs)/sizeof(*vs), vs, &fetched);
2233 ok_(__FILE__,line)(hres == S_FALSE, "Next failed: %08x\n", hres);
2234 ok_(__FILE__,line)(fetched == (len > 2 ? 2 : len), "fetched = %d\n", fetched);
2235 if(len) {
2236 ok_(__FILE__,line)(V_VT(vs) == VT_DISPATCH && V_DISPATCH(vs), "V_VT(vs[0]) = %d\n", V_VT(vs));
2237 IDispatch_Release(V_DISPATCH(vs));
2238 }
2239 if(len > 1) {
2240 ok_(__FILE__,line)(V_VT(vs+1) == VT_DISPATCH && V_DISPATCH(vs+1), "V_VT(vs[1]) = %d\n", V_VT(vs+1));
2241 IDispatch_Release(V_DISPATCH(vs+1));
2242 }
2243
2244 hres = IEnumVARIANT_Reset(enum_var);
2245 ok_(__FILE__,line)(hres == S_OK, "Reset failed: %08x\n", hres);
2246
2247 hres = IEnumVARIANT_Skip(enum_var, len+1);
2248 ok_(__FILE__,line)(hres == S_FALSE, "Skip failed: %08x\n", hres);
2249
2250 IEnumVARIANT_Release(enum_var);
2251
2252 V_VT(&name) = VT_I4;
2253 V_I4(&name) = len;
2254 disp = (void*)0xdeadbeef;
2255 hres = IHTMLElementCollection_item(col, name, index, &disp);
2256 ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2257 ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2258
2259 V_VT(&name) = VT_I4;
2260 V_I4(&name) = -1;
2261 disp = (void*)0xdeadbeef;
2262 hres = IHTMLElementCollection_item(col, name, index, &disp);
2263 ok_(__FILE__,line) (hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
2264 ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2265
2266 IHTMLElementCollection_Release(col);
2267 }
2268
2269 #define test_elem_all(c,t,l) _test_elem_all(__LINE__,c,t,l)
2270 static void _test_elem_all(unsigned line, IUnknown *unk, const elem_type_t *elem_types, LONG exlen)
2271 {
2272 IHTMLElement *elem = _get_elem_iface(line, unk);
2273 IDispatch *disp;
2274 HRESULT hres;
2275
2276 hres = IHTMLElement_get_all(elem, &disp);
2277 IHTMLElement_Release(elem);
2278 ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2279
2280 _test_elem_collection(line, (IUnknown*)disp, elem_types, exlen);
2281 IDispatch_Release(disp);
2282 }
2283
2284 #define test_doc_all(a,b,c) _test_doc_all(__LINE__,a,b,c)
2285 static void _test_doc_all(unsigned line, IHTMLDocument2 *doc, const elem_type_t *elem_types, LONG exlen)
2286 {
2287 IHTMLElementCollection *col;
2288 HRESULT hres;
2289
2290 hres = IHTMLDocument2_get_all(doc, &col);
2291 ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2292
2293 _test_elem_collection(line, (IUnknown*)col, elem_types, exlen);
2294 IHTMLElementCollection_Release(col);
2295 }
2296
2297 #define test_elem_getelembytag(a,b,c,d) _test_elem_getelembytag(__LINE__,a,b,c,d)
2298 static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t type, LONG exlen, IHTMLElement **ret)
2299 {
2300 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2301 IHTMLElementCollection *col = NULL;
2302 elem_type_t *types = NULL;
2303 BSTR tmp;
2304 int i;
2305 HRESULT hres;
2306
2307 tmp = a2bstr(elem_type_infos[type].tag);
2308 hres = IHTMLElement2_getElementsByTagName(elem, tmp, &col);
2309 SysFreeString(tmp);
2310 IHTMLElement2_Release(elem);
2311 ok_(__FILE__,line) (hres == S_OK, "getElementByTagName failed: %08x\n", hres);
2312 ok_(__FILE__,line) (col != NULL, "col == NULL\n");
2313
2314 if(exlen) {
2315 types = HeapAlloc(GetProcessHeap(), 0, exlen*sizeof(elem_type_t));
2316 for(i=0; i<exlen; i++)
2317 types[i] = type;
2318 }
2319
2320 _test_elem_collection(line, (IUnknown*)col, types, exlen);
2321
2322 HeapFree(GetProcessHeap(), 0, types);
2323
2324 if(ret)
2325 *ret = get_elem_col_item_idx(col, 0);
2326 IHTMLElementCollection_Release(col);
2327 }
2328
2329 #define test_elem_innertext(e,t) _test_elem_innertext(__LINE__,e,t)
2330 static void _test_elem_innertext(unsigned line, IHTMLElement *elem, const char *extext)
2331 {
2332 BSTR text = NULL;
2333 HRESULT hres;
2334
2335 hres = IHTMLElement_get_innerText(elem, &text);
2336 ok_(__FILE__,line) (hres == S_OK, "get_innerText failed: %08x\n", hres);
2337 if(extext)
2338 ok_(__FILE__,line) (!strcmp_wa(text, extext), "get_innerText returned %s expected %s\n",
2339 wine_dbgstr_w(text), extext);
2340 else
2341 ok_(__FILE__,line) (!text, "get_innerText returned %s expected NULL\n", wine_dbgstr_w(text));
2342 SysFreeString(text);
2343 }
2344
2345 #define test_elem_set_innertext(e,t) _test_elem_set_innertext(__LINE__,e,t)
2346 static void _test_elem_set_innertext(unsigned line, IHTMLElement *elem, const char *text)
2347 {
2348 IHTMLDOMChildrenCollection *col;
2349 BSTR str;
2350 HRESULT hres;
2351
2352 str = a2bstr(text);
2353 hres = IHTMLElement_put_innerText(elem, str);
2354 ok_(__FILE__,line) (hres == S_OK, "put_innerText failed: %08x\n", hres);
2355 SysFreeString(str);
2356
2357 _test_elem_innertext(line, elem, text);
2358
2359
2360 col = _get_child_nodes(line, (IUnknown*)elem);
2361 ok(col != NULL, "col == NULL\n");
2362 if(col) {
2363 LONG length = 0, type;
2364 IHTMLDOMNode *node;
2365
2366 hres = IHTMLDOMChildrenCollection_get_length(col, &length);
2367 ok(hres == S_OK, "get_length failed: %08x\n", hres);
2368 ok(length == 1, "length = %d\n", length);
2369
2370 node = _get_child_item(line, col, 0);
2371 ok(node != NULL, "node == NULL\n");
2372 if(node) {
2373 type = _get_node_type(line, (IUnknown*)node);
2374 ok(type == 3, "type=%d\n", type);
2375 IHTMLDOMNode_Release(node);
2376 }
2377
2378 IHTMLDOMChildrenCollection_Release(col);
2379 }
2380
2381 }
2382
2383 #define test_elem_innerhtml(e,t) _test_elem_innerhtml(__LINE__,e,t)
2384 static void _test_elem_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2385 {
2386 IHTMLElement *elem = _get_elem_iface(line, unk);
2387 BSTR html;
2388 HRESULT hres;
2389
2390 hres = IHTMLElement_get_innerHTML(elem, &html);
2391 ok_(__FILE__,line)(hres == S_OK, "get_innerHTML failed: %08x\n", hres);
2392 if(inner_html)
2393 ok_(__FILE__,line)(!strcmp_wa(html, inner_html), "unexpected innerHTML: %s\n", wine_dbgstr_w(html));
2394 else
2395 ok_(__FILE__,line)(!html, "innerHTML = %s\n", wine_dbgstr_w(html));
2396
2397 IHTMLElement_Release(elem);
2398 SysFreeString(html);
2399 }
2400
2401 #define test_elem_set_innerhtml(e,t) _test_elem_set_innerhtml(__LINE__,e,t)
2402 static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2403 {
2404 IHTMLElement *elem = _get_elem_iface(line, unk);
2405 BSTR html;
2406 HRESULT hres;
2407
2408 html = a2bstr(inner_html);
2409 hres = IHTMLElement_put_innerHTML(elem, html);
2410 ok_(__FILE__,line)(hres == S_OK, "put_innerHTML failed: %08x\n", hres);
2411
2412 IHTMLElement_Release(elem);
2413 SysFreeString(html);
2414 }
2415
2416 #define test_elem_set_outerhtml(e,t) _test_elem_set_outerhtml(__LINE__,e,t)
2417 static void _test_elem_set_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2418 {
2419 IHTMLElement *elem = _get_elem_iface(line, unk);
2420 BSTR html;
2421 HRESULT hres;
2422
2423 html = a2bstr(outer_html);
2424 hres = IHTMLElement_put_outerHTML(elem, html);
2425 ok_(__FILE__,line)(hres == S_OK, "put_outerHTML failed: %08x\n", hres);
2426
2427 IHTMLElement_Release(elem);
2428 SysFreeString(html);
2429 }
2430
2431 #define test_elem_outerhtml(e,t) _test_elem_outerhtml(__LINE__,e,t)
2432 static void _test_elem_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2433 {
2434 IHTMLElement *elem = _get_elem_iface(line, unk);
2435 BSTR html;
2436 HRESULT hres;
2437
2438 hres = IHTMLElement_get_outerHTML(elem, &html);
2439 ok_(__FILE__,line)(hres == S_OK, "get_outerHTML failed: %08x\n", hres);
2440 ok_(__FILE__,line)(!strcmp_wa(html, outer_html), "outerHTML = '%s', expected '%s'\n", wine_dbgstr_w(html), outer_html);
2441
2442 IHTMLElement_Release(elem);
2443 SysFreeString(html);
2444 }
2445
2446 #define test_elem_contains(a,b,c) _test_elem_contains(__LINE__,a,b,c)
2447 static void _test_elem_contains(unsigned line, IHTMLElement *elem, IHTMLElement *elem2, VARIANT_BOOL exval)
2448 {
2449 VARIANT_BOOL b;
2450 HRESULT hres;
2451
2452 b = 100;
2453 hres = IHTMLElement_contains(elem, elem2, &b);
2454 ok_(__FILE__,line)(hres == S_OK, "contains failed: %08x\n", hres);
2455 ok_(__FILE__,line)(b == exval, "contains returned %x, expected %x\n", b, exval);
2456 }
2457
2458 #define get_first_child(n) _get_first_child(__LINE__,n)
2459 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
2460 {
2461 IHTMLDOMNode *node = _get_node_iface(line, unk);
2462 IHTMLDOMNode *child = NULL;
2463 HRESULT hres;
2464
2465 hres = IHTMLDOMNode_get_firstChild(node, &child);
2466 IHTMLDOMNode_Release(node);
2467 ok_(__FILE__,line) (hres == S_OK, "get_firstChild failed: %08x\n", hres);
2468
2469 return child;
2470 }
2471
2472 #define test_node_has_child(u,b) _test_node_has_child(__LINE__,u,b)
2473 static void _test_node_has_child(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2474 {
2475 IHTMLDOMNode *node = _get_node_iface(line, unk);
2476 VARIANT_BOOL b = 0xdead;
2477 HRESULT hres;
2478
2479 hres = IHTMLDOMNode_hasChildNodes(node, &b);
2480 ok_(__FILE__,line) (hres == S_OK, "hasChildNodes failed: %08x\n", hres);
2481 ok_(__FILE__,line) (b == exb, "hasChildNodes=%x, expected %x\n", b, exb);
2482
2483 IHTMLDOMNode_Release(node);
2484 }
2485
2486 #define test_node_get_parent(u) _test_node_get_parent(__LINE__,u)
2487 static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
2488 {
2489 IHTMLDOMNode *node = _get_node_iface(line, unk);
2490 IHTMLDOMNode *parent;
2491 HRESULT hres;
2492
2493 hres = IHTMLDOMNode_get_parentNode(node, &parent);
2494 IHTMLDOMNode_Release(node);
2495 ok_(__FILE__,line) (hres == S_OK, "get_parentNode failed: %08x\n", hres);
2496
2497 return parent;
2498 }
2499
2500 #define node_get_next(u) _node_get_next(__LINE__,u)
2501 static IHTMLDOMNode *_node_get_next(unsigned line, IUnknown *unk)
2502 {
2503 IHTMLDOMNode *node = _get_node_iface(line, unk);
2504 IHTMLDOMNode *next;
2505 HRESULT hres;
2506
2507 hres = IHTMLDOMNode_get_nextSibling(node, &next);
2508 IHTMLDOMNode_Release(node);
2509 ok_(__FILE__,line) (hres == S_OK, "get_nextSiblibg failed: %08x\n", hres);
2510
2511 return next;
2512 }
2513
2514 #define node_get_prev(u) _node_get_prev(__LINE__,u)
2515 static IHTMLDOMNode *_node_get_prev(unsigned line, IUnknown *unk)
2516 {
2517 IHTMLDOMNode *node = _get_node_iface(line, unk);
2518 IHTMLDOMNode *prev;
2519 HRESULT hres;
2520
2521 hres = IHTMLDOMNode_get_previousSibling(node, &prev);
2522 IHTMLDOMNode_Release(node);
2523 ok_(__FILE__,line) (hres == S_OK, "get_previousSibling failed: %08x\n", hres);
2524
2525 return prev;
2526 }
2527
2528 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
2529 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
2530 {
2531 IHTMLElement *elem = _get_elem_iface(line, unk);
2532 IHTMLElement *parent;
2533 HRESULT hres;
2534
2535 hres = IHTMLElement_get_parentElement(elem, &parent);
2536 IHTMLElement_Release(elem);
2537 ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
2538
2539 return parent;
2540 }
2541
2542 #define test_elem3_get_disabled(i,b) _test_elem3_get_disabled(__LINE__,i,b)
2543 static void _test_elem3_get_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2544 {
2545 IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2546 VARIANT_BOOL disabled = 100;
2547 HRESULT hres;
2548
2549 if (!elem3) return;
2550 hres = IHTMLElement3_get_disabled(elem3, &disabled);
2551 ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2552 ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2553 IHTMLElement3_Release(elem3);
2554 }
2555
2556 #define test_elem3_set_disabled(i,b) _test_elem3_set_disabled(__LINE__,i,b)
2557 static void _test_elem3_set_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL b)
2558 {
2559 IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2560 HRESULT hres;
2561
2562 if (!elem3) return;
2563 hres = IHTMLElement3_put_disabled(elem3, b);
2564 ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2565
2566 IHTMLElement3_Release(elem3);
2567 _test_elem3_get_disabled(line, unk, b);
2568 }
2569
2570 #define test_select_get_disabled(i,b) _test_select_get_disabled(__LINE__,i,b)
2571 static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exb)
2572 {
2573 VARIANT_BOOL disabled = 100;
2574 HRESULT hres;
2575
2576 hres = IHTMLSelectElement_get_disabled(select, &disabled);
2577 ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2578 ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2579
2580 _test_elem3_get_disabled(line, (IUnknown*)select, exb);
2581 }
2582
2583 static void test_select_remove(IHTMLSelectElement *select)
2584 {
2585 HRESULT hres;
2586
2587 hres = IHTMLSelectElement_remove(select, 3);
2588 ok(hres == S_OK, "remove failed: %08x, expected S_OK\n", hres);
2589 test_select_length(select, 2);
2590
2591 hres = IHTMLSelectElement_remove(select, -1);
2592 todo_wine
2593 ok(hres == E_INVALIDARG, "remove failed: %08x, expected E_INVALIDARG\n", hres);
2594 test_select_length(select, 2);
2595
2596 hres = IHTMLSelectElement_remove(select, 0);
2597 ok(hres == S_OK, "remove failed:%08x\n", hres);
2598 test_select_length(select, 1);
2599 }
2600
2601 #define test_text_length(u,l) _test_text_length(__LINE__,u,l)
2602 static void _test_text_length(unsigned line, IUnknown *unk, LONG l)
2603 {
2604 IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2605 LONG length;
2606 HRESULT hres;
2607
2608 hres = IHTMLDOMTextNode_get_length(text, &length);
2609 ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
2610 ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l);
2611 IHTMLDOMTextNode_Release(text);
2612 }
2613
2614 #define test_text_data(a,b) _test_text_data(__LINE__,a,b)
2615 static void _test_text_data(unsigned line, IUnknown *unk, const char *exdata)
2616 {
2617 IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2618 BSTR str;
2619 HRESULT hres;
2620
2621 hres = IHTMLDOMTextNode_get_data(text, &str);
2622 ok_(__FILE__,line)(hres == S_OK, "get_data failed: %08x\n", hres);
2623 ok_(__FILE__,line)(!strcmp_wa(str, exdata), "data = %s, expected %s\n", wine_dbgstr_w(str), exdata);
2624 IHTMLDOMTextNode_Release(text);
2625 SysFreeString(str);
2626 }
2627
2628 #define set_text_data(a,b) _set_text_data(__LINE__,a,b)
2629 static void _set_text_data(unsigned line, IUnknown *unk, const char *data)
2630 {
2631 IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2632 BSTR str = a2bstr(data);
2633 HRESULT hres;
2634
2635 hres = IHTMLDOMTextNode_put_data(text, str);
2636 ok_(__FILE__,line)(hres == S_OK, "get_data failed: %08x\n", hres);
2637 IHTMLDOMTextNode_Release(text);
2638 SysFreeString(str);
2639 }
2640
2641 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
2642 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
2643 {
2644 HRESULT hres;
2645
2646 hres = IHTMLSelectElement_put_disabled(select, b);
2647 ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2648
2649 _test_select_get_disabled(line, select, b);
2650 }
2651
2652 #define elem_get_scroll_height(u) _elem_get_scroll_height(__LINE__,u)
2653 static LONG _elem_get_scroll_height(unsigned line, IUnknown *unk)
2654 {
2655 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2656 IHTMLTextContainer *txtcont;
2657 LONG l = -1, l2 = -1;
2658 HRESULT hres;
2659
2660 hres = IHTMLElement2_get_scrollHeight(elem, &l);
2661 ok_(__FILE__,line) (hres == S_OK, "get_scrollHeight failed: %08x\n", hres);
2662 IHTMLElement2_Release(elem);
2663
2664 hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2665 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2666
2667 hres = IHTMLTextContainer_get_scrollHeight(txtcont, &l2);
2668 IHTMLTextContainer_Release(txtcont);
2669 ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollHeight failed: %d\n", l2);
2670 ok_(__FILE__,line) (l == l2, "unexpected height %d, expected %d\n", l2, l);
2671
2672 return l;
2673 }
2674
2675 #define elem_get_scroll_width(u) _elem_get_scroll_width(__LINE__,u)
2676 static LONG _elem_get_scroll_width(unsigned line, IUnknown *unk)
2677 {
2678 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2679 IHTMLTextContainer *txtcont;
2680 LONG l = -1, l2 = -1;
2681 HRESULT hres;
2682
2683 hres = IHTMLElement2_get_scrollWidth(elem, &l);
2684 ok_(__FILE__,line) (hres == S_OK, "get_scrollWidth failed: %08x\n", hres);
2685 IHTMLElement2_Release(elem);
2686
2687 hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2688 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2689
2690 hres = IHTMLTextContainer_get_scrollWidth(txtcont, &l2);
2691 IHTMLTextContainer_Release(txtcont);
2692 ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollWidth failed: %d\n", l2);
2693 ok_(__FILE__,line) (l == l2, "unexpected width %d, expected %d\n", l2, l);
2694
2695 return l;
2696 }
2697
2698 #define elem_get_scroll_top(u) _elem_get_scroll_top(__LINE__,u)
2699 static LONG _elem_get_scroll_top(unsigned line, IUnknown *unk)
2700 {
2701 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2702 IHTMLTextContainer *txtcont;
2703 LONG l = -1, l2 = -1;
2704 HRESULT hres;
2705
2706 hres = IHTMLElement2_get_scrollTop(elem, &l);
2707 ok_(__FILE__,line) (hres == S_OK, "get_scrollTop failed: %08x\n", hres);
2708 IHTMLElement2_Release(elem);
2709
2710 hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2711 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2712
2713 hres = IHTMLTextContainer_get_scrollTop(txtcont, &l2);
2714 IHTMLTextContainer_Release(txtcont);
2715 ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollTop failed: %d\n", l2);
2716 ok_(__FILE__,line) (l == l2, "unexpected top %d, expected %d\n", l2, l);
2717
2718 return l;
2719 }
2720
2721 #define elem_get_scroll_left(u) _elem_get_scroll_left(__LINE__,u)
2722 static void _elem_get_scroll_left(unsigned line, IUnknown *unk)
2723 {
2724 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2725 IHTMLTextContainer *txtcont;
2726 LONG l = -1, l2 = -1;
2727 HRESULT hres;
2728
2729 hres = IHTMLElement2_get_scrollLeft(elem, NULL);
2730 ok(hres == E_INVALIDARG, "expect E_INVALIDARG got 0x%08x\n", hres);
2731
2732 hres = IHTMLElement2_get_scrollLeft(elem, &l);
2733 ok(hres == S_OK, "get_scrollTop failed: %08x\n", hres);
2734 IHTMLElement2_Release(elem);
2735
2736 hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2737 ok(hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2738
2739 hres = IHTMLTextContainer_get_scrollLeft(txtcont, &l2);
2740 IHTMLTextContainer_Release(txtcont);
2741 ok(hres == S_OK, "IHTMLTextContainer::get_scrollLeft failed: %d\n", l2);
2742 ok(l == l2, "unexpected left %d, expected %d\n", l2, l);
2743 }
2744
2745 #define test_img_src(a,b,c) _test_img_src(__LINE__,a,b,c)
2746 static void _test_img_src(unsigned line, IUnknown *unk, const char *exsrc, const char *broken_src)
2747 {
2748 IHTMLImgElement *img = _get_img_iface(line, unk);
2749 BSTR src;
2750 HRESULT hres;
2751
2752 hres = IHTMLImgElement_get_src(img, &src);
2753 IHTMLImgElement_Release(img);
2754 ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
2755 ok_(__FILE__,line) (!strcmp_wa(src, exsrc) || (broken_src && broken(!strcmp_wa(src, broken_src))),
2756 "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
2757 SysFreeString(src);
2758 }
2759
2760 #define test_img_set_src(u,s) _test_img_set_src(__LINE__,u,s)
2761 static void _test_img_set_src(unsigned line, IUnknown *unk, const char *src)
2762 {
2763 IHTMLImgElement *img = _get_img_iface(line, unk);
2764 BSTR tmp;
2765 HRESULT hres;
2766
2767 tmp = a2bstr(src);
2768 hres = IHTMLImgElement_put_src(img, tmp);
2769 IHTMLImgElement_Release(img);
2770 SysFreeString(tmp);
2771 ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
2772 }
2773
2774 #define test_img_alt(u,a) _test_img_alt(__LINE__,u,a)
2775 static void _test_img_alt(unsigned line, IUnknown *unk, const char *exalt)
2776 {
2777 IHTMLImgElement *img = _get_img_iface(line, unk);
2778 BSTR alt;
2779 HRESULT hres;
2780
2781 hres = IHTMLImgElement_get_alt(img, &alt);
2782 ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
2783 if(exalt)
2784 ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "inexopected alt %s\n", wine_dbgstr_w(alt));
2785 else
2786 ok_(__FILE__,line) (!alt, "alt != NULL\n");
2787 SysFreeString(alt);
2788 }
2789
2790 #define test_img_set_alt(u,a) _test_img_set_alt(__LINE__,u,a)
2791 static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
2792 {
2793 IHTMLImgElement *img = _get_img_iface(line, unk);
2794 BSTR tmp;
2795 HRESULT hres;
2796
2797 tmp = a2bstr(alt);
2798 hres = IHTMLImgElement_put_alt(img, tmp);
2799 ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
2800 SysFreeString(tmp);
2801
2802 _test_img_alt(line, unk, alt);
2803 }
2804
2805 #define test_img_align(u,a) _test_img_align(__LINE__,u,a)
2806 static void _test_img_align(unsigned line, IUnknown *unk, const char *align)
2807 {
2808 IHTMLImgElement *img = _get_img_iface(line, unk);
2809 BSTR tmp;
2810 HRESULT hres;
2811
2812 tmp = a2bstr(align);
2813 hres = IHTMLImgElement_put_align(img, tmp);
2814 ok_(__FILE__,line) (hres == S_OK, "put_align failed: %08x\n", hres);
2815 SysFreeString(tmp);
2816
2817 hres = IHTMLImgElement_get_align(img, &tmp);
2818 ok_(__FILE__,line) (hres == S_OK, "put_align failed: %08x\n", hres);
2819 ok_(__FILE__,line) (!strcmp_wa(tmp, align), "Expect %s, got %s\n", align, wine_dbgstr_w(tmp));
2820 SysFreeString(tmp);
2821 }
2822
2823 #define test_img_name(u, c) _test_img_name(__LINE__,u, c)
2824 static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue)
2825 {
2826 IHTMLImgElement *img = _get_img_iface(line, unk);
2827 BSTR sName;
2828 HRESULT hres;
2829
2830 hres = IHTMLImgElement_get_name(img, &sName);
2831 ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres);
2832 ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName));
2833 IHTMLImgElement_Release(img);
2834 SysFreeString(sName);
2835 }
2836
2837 #define test_img_complete(a,b) _test_img_complete(__LINE__,a,b)
2838 static void _test_img_complete(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
2839 {
2840 IHTMLImgElement *img = _get_img_iface(line, (IUnknown*)elem);
2841 VARIANT_BOOL b = 100;
2842 HRESULT hres;
2843
2844 hres = IHTMLImgElement_get_complete(img, &b);
2845 ok_(__FILE__,line) (hres == S_OK, "get_complete failed: %08x\n", hres);
2846 ok_(__FILE__,line) (b == exb, "complete = %x, expected %x\n", b, exb);
2847 IHTMLImgElement_Release(img);
2848 }
2849
2850 #define test_img_isMap(u, c) _test_img_isMap(__LINE__,u, c)
2851 static void _test_img_isMap(unsigned line, IUnknown *unk, VARIANT_BOOL v)
2852 {
2853 IHTMLImgElement *img = _get_img_iface(line, unk);
2854 VARIANT_BOOL b = 100;
2855 HRESULT hres;
2856
2857 hres = IHTMLImgElement_put_isMap(img, v);
2858 ok_(__FILE__,line) (hres == S_OK, "put_isMap failed: %08x\n", hres);
2859
2860 hres = IHTMLImgElement_get_isMap(img, &b);
2861 ok_(__FILE__,line) (hres == S_OK, "get_isMap failed: %08x\n", hres);
2862 ok_(__FILE__,line) (b == v, "isMap = %x, expected %x\n", b, v);
2863
2864 hres = IHTMLImgElement_get_isMap(img, NULL);
2865 ok_(__FILE__,line) (hres == E_INVALIDARG, "ret = %08x, expected E_INVALIDARG\n", hres);
2866 IHTMLImgElement_Release(img);
2867 }
2868
2869 static void test_dynamic_properties(IHTMLElement *elem)
2870 {
2871 static const WCHAR attr1W[] = {'a','t','t','r','1',0};
2872 IDispatchEx *dispex;
2873 BSTR name, attr1 = SysAllocString(attr1W);
2874 VARIANT_BOOL succ;
2875 VARIANT val;
2876 int checked_no = 0;
2877 DISPID id = DISPID_STARTENUM;
2878 HRESULT hres;
2879
2880 hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
2881 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2882
2883 hres = IHTMLElement_removeAttribute(elem, attr1, 0, &succ);
2884 ok(hres == S_OK, "removeAttribute failed: %08x\n", hres);
2885 ok(succ, "removeAttribute set succ to FALSE\n");
2886
2887 while(1) {
2888 hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, id, &id);
2889 ok(hres==S_OK || hres==S_FALSE, "GetNextDispID failed: %08x\n", hres);
2890 if(hres != S_OK)
2891 break;
2892
2893 hres = IDispatchEx_GetMemberName(dispex, id, &name);
2894 ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
2895
2896 if(!strcmp_wa(name, "attr1"))
2897 ok(0, "attr1 should be removed\n");
2898 else if(!strcmp_wa(name, "attr2") || !strcmp_wa(name, "attr3"))
2899 checked_no++;
2900 SysFreeString(name);
2901 }
2902 ok(checked_no == 2, "checked_no=%d, expected 2\n", checked_no);
2903 IDispatchEx_Release(dispex);
2904
2905 V_VT(&val) = VT_BSTR;
2906 V_BSTR(&val) = attr1;
2907 hres = IHTMLElement_setAttribute(elem, attr1, val, 0);
2908 ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
2909 SysFreeString(attr1);
2910 }
2911
2912 #define test_attr_node_name(a,b) _test_attr_node_name(__LINE__,a,b)
2913 static void _test_attr_node_name(unsigned line, IHTMLDOMAttribute *attr, const char *exname)
2914 {
2915 BSTR str;
2916 HRESULT hres;
2917
2918 hres = IHTMLDOMAttribute_get_nodeName(attr, &str);
2919 ok_(__FILE__,line)(hres == S_OK, "get_nodeName failed: %08x\n", hres);
2920 ok_(__FILE__,line)(!strcmp_wa(str, exname), "node name is %s, expected %s\n", wine_dbgstr_w(str), exname);
2921 SysFreeString(str);
2922 }
2923
2924 static void test_attr_collection_disp(IDispatch *disp)
2925 {
2926 IDispatchEx *dispex;
2927 IHTMLDOMAttribute *attr;
2928 DISPPARAMS dp = {NULL, NULL, 0, 0};
2929 VARIANT var;
2930 EXCEPINFO ei;
2931 DISPID id;
2932 BSTR bstr;
2933 HRESULT hres;
2934
2935 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2936 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2937
2938 bstr = a2bstr("0");
2939 hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
2940 ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2941 SysFreeString(bstr);
2942
2943 VariantInit(&var);
2944 hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2945 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2946 ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2947 ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");