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