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