[INTRIN]
[reactos.git] / reactos / base / shell / ie / mshtml / htmlelem.c
1 /*
2 * Copyright 2006 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 "mshtml_private.h"
20
21 static const WCHAR aW[] = {'A',0};
22 static const WCHAR bodyW[] = {'B','O','D','Y',0};
23 static const WCHAR buttonW[] = {'B','U','T','T','O','N',0};
24 static const WCHAR embedW[] = {'E','M','B','E','D',0};
25 static const WCHAR formW[] = {'F','O','R','M',0};
26 static const WCHAR frameW[] = {'F','R','A','M','E',0};
27 static const WCHAR headW[] = {'H','E','A','D',0};
28 static const WCHAR iframeW[] = {'I','F','R','A','M','E',0};
29 static const WCHAR imgW[] = {'I','M','G',0};
30 static const WCHAR inputW[] = {'I','N','P','U','T',0};
31 static const WCHAR labelW[] = {'L','A','B','E','L',0};
32 static const WCHAR linkW[] = {'L','I','N','K',0};
33 static const WCHAR metaW[] = {'M','E','T','A',0};
34 static const WCHAR objectW[] = {'O','B','J','E','C','T',0};
35 static const WCHAR optionW[] = {'O','P','T','I','O','N',0};
36 static const WCHAR scriptW[] = {'S','C','R','I','P','T',0};
37 static const WCHAR selectW[] = {'S','E','L','E','C','T',0};
38 static const WCHAR styleW[] = {'S','T','Y','L','E',0};
39 static const WCHAR tableW[] = {'T','A','B','L','E',0};
40 static const WCHAR tdW[] = {'T','D',0};
41 static const WCHAR textareaW[] = {'T','E','X','T','A','R','E','A',0};
42 static const WCHAR title_tagW[]= {'T','I','T','L','E',0};
43 static const WCHAR trW[] = {'T','R',0};
44
45 typedef struct {
46 const WCHAR *name;
47 HRESULT (*constructor)(HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLElement**);
48 } tag_desc_t;
49
50 static const tag_desc_t tag_descs[] = {
51 {aW, HTMLAnchorElement_Create},
52 {bodyW, HTMLBodyElement_Create},
53 {buttonW, HTMLButtonElement_Create},
54 {embedW, HTMLEmbedElement_Create},
55 {formW, HTMLFormElement_Create},
56 {frameW, HTMLFrameElement_Create},
57 {headW, HTMLHeadElement_Create},
58 {iframeW, HTMLIFrame_Create},
59 {imgW, HTMLImgElement_Create},
60 {inputW, HTMLInputElement_Create},
61 {labelW, HTMLLabelElement_Create},
62 {linkW, HTMLLinkElement_Create},
63 {metaW, HTMLMetaElement_Create},
64 {objectW, HTMLObjectElement_Create},
65 {optionW, HTMLOptionElement_Create},
66 {scriptW, HTMLScriptElement_Create},
67 {selectW, HTMLSelectElement_Create},
68 {styleW, HTMLStyleElement_Create},
69 {tableW, HTMLTable_Create},
70 {tdW, HTMLTableCell_Create},
71 {textareaW, HTMLTextAreaElement_Create},
72 {title_tagW, HTMLTitleElement_Create},
73 {trW, HTMLTableRow_Create}
74 };
75
76 static const tag_desc_t *get_tag_desc(const WCHAR *tag_name)
77 {
78 DWORD min=0, max=sizeof(tag_descs)/sizeof(*tag_descs)-1, i;
79 int r;
80
81 while(min <= max) {
82 i = (min+max)/2;
83 r = strcmpW(tag_name, tag_descs[i].name);
84 if(!r)
85 return tag_descs+i;
86
87 if(r < 0)
88 max = i-1;
89 else
90 min = i+1;
91 }
92
93 return NULL;
94 }
95
96 HRESULT replace_node_by_html(nsIDOMHTMLDocument *nsdoc, nsIDOMNode *nsnode, const WCHAR *html)
97 {
98 nsIDOMDocumentFragment *nsfragment;
99 nsIDOMNode *nsparent;
100 nsIDOMRange *range;
101 nsAString html_str;
102 nsresult nsres;
103 HRESULT hres = S_OK;
104
105 nsres = nsIDOMHTMLDocument_CreateRange(nsdoc, &range);
106 if(NS_FAILED(nsres)) {
107 ERR("CreateRange failed: %08x\n", nsres);
108 return E_FAIL;
109 }
110
111 nsAString_InitDepend(&html_str, html);
112 nsIDOMRange_CreateContextualFragment(range, &html_str, &nsfragment);
113 nsIDOMRange_Release(range);
114 nsAString_Finish(&html_str);
115 if(NS_FAILED(nsres)) {
116 ERR("CreateContextualFragment failed: %08x\n", nsres);
117 return E_FAIL;
118 }
119
120 nsres = nsIDOMNode_GetParentNode(nsnode, &nsparent);
121 if(NS_SUCCEEDED(nsres) && nsparent) {
122 nsIDOMNode *nstmp;
123
124 nsres = nsIDOMNode_ReplaceChild(nsparent, (nsIDOMNode*)nsfragment, nsnode, &nstmp);
125 nsIDOMNode_Release(nsparent);
126 if(NS_FAILED(nsres)) {
127 ERR("ReplaceChild failed: %08x\n", nsres);
128 hres = E_FAIL;
129 }else if(nstmp) {
130 nsIDOMNode_Release(nstmp);
131 }
132 }else {
133 ERR("GetParentNode failed: %08x\n", nsres);
134 hres = E_FAIL;
135 }
136
137 nsIDOMDocumentFragment_Release(nsfragment);
138 return hres;
139 }
140
141 nsresult get_elem_attr_value(nsIDOMHTMLElement *nselem, const WCHAR *name, nsAString *val_str, const PRUnichar **val)
142 {
143 nsAString name_str;
144 nsresult nsres;
145
146 nsAString_InitDepend(&name_str, name);
147 nsAString_Init(val_str, NULL);
148 nsres = nsIDOMHTMLElement_GetAttribute(nselem, &name_str, val_str);
149 nsAString_Finish(&name_str);
150 if(NS_FAILED(nsres)) {
151 ERR("GetAttribute(%s) failed: %08x\n", debugstr_w(name), nsres);
152 nsAString_Finish(val_str);
153 return nsres;
154 }
155
156 nsAString_GetData(val_str, val);
157 return NS_OK;
158 }
159
160 HRESULT elem_string_attr_getter(HTMLElement *elem, const WCHAR *name, BOOL use_null, BSTR *p)
161 {
162 const PRUnichar *val;
163 nsAString val_str;
164 nsresult nsres;
165 HRESULT hres = S_OK;
166
167 nsres = get_elem_attr_value(elem->nselem, name, &val_str, &val);
168 if(NS_FAILED(nsres))
169 return E_FAIL;
170
171 TRACE("%s: returning %s\n", debugstr_w(name), debugstr_w(val));
172
173 if(*val || !use_null) {
174 *p = SysAllocString(val);
175 if(!*p)
176 hres = E_OUTOFMEMORY;
177 }else {
178 *p = NULL;
179 }
180 nsAString_Finish(&val_str);
181 return hres;
182 }
183
184 HRESULT elem_string_attr_setter(HTMLElement *elem, const WCHAR *name, const WCHAR *value)
185 {
186 nsAString name_str, val_str;
187 nsresult nsres;
188
189 nsAString_InitDepend(&name_str, name);
190 nsAString_InitDepend(&val_str, value);
191 nsres = nsIDOMHTMLElement_SetAttribute(elem->nselem, &name_str, &val_str);
192 nsAString_Finish(&name_str);
193 nsAString_Finish(&val_str);
194
195 if(NS_FAILED(nsres)) {
196 WARN("SetAttribute failed: %08x\n", nsres);
197 return E_FAIL;
198 }
199
200 return S_OK;
201 }
202
203 typedef struct
204 {
205 DispatchEx dispex;
206 IHTMLFiltersCollection IHTMLFiltersCollection_iface;
207
208 LONG ref;
209 } HTMLFiltersCollection;
210
211 static inline HTMLFiltersCollection *impl_from_IHTMLFiltersCollection(IHTMLFiltersCollection *iface)
212 {
213 return CONTAINING_RECORD(iface, HTMLFiltersCollection, IHTMLFiltersCollection_iface);
214 }
215
216 static IHTMLFiltersCollection *HTMLFiltersCollection_Create(void);
217
218 static inline HTMLElement *impl_from_IHTMLElement(IHTMLElement *iface)
219 {
220 return CONTAINING_RECORD(iface, HTMLElement, IHTMLElement_iface);
221 }
222
223 HRESULT create_nselem(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMHTMLElement **ret)
224 {
225 nsIDOMElement *nselem;
226 nsAString tag_str;
227 nsresult nsres;
228
229 if(!doc->nsdoc) {
230 WARN("NULL nsdoc\n");
231 return E_UNEXPECTED;
232 }
233
234 nsAString_InitDepend(&tag_str, tag);
235 nsres = nsIDOMHTMLDocument_CreateElement(doc->nsdoc, &tag_str, &nselem);
236 nsAString_Finish(&tag_str);
237 if(NS_FAILED(nsres)) {
238 ERR("CreateElement failed: %08x\n", nsres);
239 return E_FAIL;
240 }
241
242 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLElement, (void**)ret);
243 nsIDOMElement_Release(nselem);
244 if(NS_FAILED(nsres)) {
245 ERR("Could not get nsIDOMHTMLElement iface: %08x\n", nsres);
246 return E_FAIL;
247 }
248
249 return S_OK;
250 }
251
252 HRESULT create_element(HTMLDocumentNode *doc, const WCHAR *tag, HTMLElement **ret)
253 {
254 nsIDOMHTMLElement *nselem;
255 HRESULT hres;
256
257 /* Use owner doc if called on document fragment */
258 if(!doc->nsdoc)
259 doc = doc->node.doc;
260
261 hres = create_nselem(doc, tag, &nselem);
262 if(FAILED(hres))
263 return hres;
264
265 hres = HTMLElement_Create(doc, (nsIDOMNode*)nselem, TRUE, ret);
266 nsIDOMHTMLElement_Release(nselem);
267 return hres;
268 }
269
270 static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface,
271 REFIID riid, void **ppv)
272 {
273 HTMLElement *This = impl_from_IHTMLElement(iface);
274
275 return IHTMLDOMNode_QueryInterface(&This->node.IHTMLDOMNode_iface, riid, ppv);
276 }
277
278 static ULONG WINAPI HTMLElement_AddRef(IHTMLElement *iface)
279 {
280 HTMLElement *This = impl_from_IHTMLElement(iface);
281
282 return IHTMLDOMNode_AddRef(&This->node.IHTMLDOMNode_iface);
283 }
284
285 static ULONG WINAPI HTMLElement_Release(IHTMLElement *iface)
286 {
287 HTMLElement *This = impl_from_IHTMLElement(iface);
288
289 return IHTMLDOMNode_Release(&This->node.IHTMLDOMNode_iface);
290 }
291
292 static HRESULT WINAPI HTMLElement_GetTypeInfoCount(IHTMLElement *iface, UINT *pctinfo)
293 {
294 HTMLElement *This = impl_from_IHTMLElement(iface);
295 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
296 }
297
298 static HRESULT WINAPI HTMLElement_GetTypeInfo(IHTMLElement *iface, UINT iTInfo,
299 LCID lcid, ITypeInfo **ppTInfo)
300 {
301 HTMLElement *This = impl_from_IHTMLElement(iface);
302 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
303 }
304
305 static HRESULT WINAPI HTMLElement_GetIDsOfNames(IHTMLElement *iface, REFIID riid,
306 LPOLESTR *rgszNames, UINT cNames,
307 LCID lcid, DISPID *rgDispId)
308 {
309 HTMLElement *This = impl_from_IHTMLElement(iface);
310 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
311 lcid, rgDispId);
312 }
313
314 static HRESULT WINAPI HTMLElement_Invoke(IHTMLElement *iface, DISPID dispIdMember,
315 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
316 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
317 {
318 HTMLElement *This = impl_from_IHTMLElement(iface);
319 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
320 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
321 }
322
323 static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttributeName,
324 VARIANT AttributeValue, LONG lFlags)
325 {
326 HTMLElement *This = impl_from_IHTMLElement(iface);
327 HRESULT hres;
328 DISPID dispid, dispidNamed = DISPID_PROPERTYPUT;
329 DISPPARAMS dispParams;
330 EXCEPINFO excep;
331
332 TRACE("(%p)->(%s %s %08x)\n", This, debugstr_w(strAttributeName), debugstr_variant(&AttributeValue), lFlags);
333
334 hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, strAttributeName,
335 fdexNameCaseInsensitive | fdexNameEnsure, &dispid);
336 if(FAILED(hres))
337 return hres;
338
339 dispParams.cArgs = 1;
340 dispParams.cNamedArgs = 1;
341 dispParams.rgdispidNamedArgs = &dispidNamed;
342 dispParams.rgvarg = &AttributeValue;
343
344 hres = IDispatchEx_InvokeEx(&This->node.dispex.IDispatchEx_iface, dispid,
345 LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams, NULL, &excep, NULL);
346 return hres;
347 }
348
349 static HRESULT WINAPI HTMLElement_getAttribute(IHTMLElement *iface, BSTR strAttributeName,
350 LONG lFlags, VARIANT *AttributeValue)
351 {
352 HTMLElement *This = impl_from_IHTMLElement(iface);
353 DISPID dispid;
354 HRESULT hres;
355 DISPPARAMS dispParams = {NULL, NULL, 0, 0};
356 EXCEPINFO excep;
357
358 TRACE("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue);
359
360 hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, strAttributeName,
361 fdexNameCaseInsensitive, &dispid);
362 if(hres == DISP_E_UNKNOWNNAME) {
363 V_VT(AttributeValue) = VT_NULL;
364 return S_OK;
365 }
366
367 if(FAILED(hres)) {
368 V_VT(AttributeValue) = VT_NULL;
369 return hres;
370 }
371
372 hres = IDispatchEx_InvokeEx(&This->node.dispex.IDispatchEx_iface, dispid, LOCALE_SYSTEM_DEFAULT,
373 DISPATCH_PROPERTYGET, &dispParams, AttributeValue, &excep, NULL);
374
375 return hres;
376 }
377
378 static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strAttributeName,
379 LONG lFlags, VARIANT_BOOL *pfSuccess)
380 {
381 HTMLElement *This = impl_from_IHTMLElement(iface);
382
383 TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
384
385 return remove_prop(&This->node.dispex, strAttributeName, pfSuccess);
386 }
387
388 static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
389 {
390 HTMLElement *This = impl_from_IHTMLElement(iface);
391 nsAString classname_str;
392 nsresult nsres;
393
394 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
395
396 if(!This->nselem) {
397 FIXME("NULL nselem\n");
398 return E_NOTIMPL;
399 }
400
401 nsAString_InitDepend(&classname_str, v);
402 nsres = nsIDOMHTMLElement_SetClassName(This->nselem, &classname_str);
403 nsAString_Finish(&classname_str);
404 if(NS_FAILED(nsres))
405 ERR("SetClassName failed: %08x\n", nsres);
406
407 return S_OK;
408 }
409
410 static HRESULT WINAPI HTMLElement_get_className(IHTMLElement *iface, BSTR *p)
411 {
412 HTMLElement *This = impl_from_IHTMLElement(iface);
413 nsAString class_str;
414 nsresult nsres;
415
416 TRACE("(%p)->(%p)\n", This, p);
417
418 if(!This->nselem) {
419 FIXME("NULL nselem\n");
420 return E_NOTIMPL;
421 }
422
423 nsAString_Init(&class_str, NULL);
424 nsres = nsIDOMHTMLElement_GetClassName(This->nselem, &class_str);
425 return return_nsstr(nsres, &class_str, p);
426 }
427
428 static HRESULT WINAPI HTMLElement_put_id(IHTMLElement *iface, BSTR v)
429 {
430 HTMLElement *This = impl_from_IHTMLElement(iface);
431 nsAString id_str;
432 nsresult nsres;
433
434 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
435
436 if(!This->nselem) {
437 FIXME("nselem == NULL\n");
438 return S_OK;
439 }
440
441 nsAString_InitDepend(&id_str, v);
442 nsres = nsIDOMHTMLElement_SetId(This->nselem, &id_str);
443 nsAString_Finish(&id_str);
444 if(NS_FAILED(nsres))
445 ERR("SetId failed: %08x\n", nsres);
446
447 return S_OK;
448 }
449
450 static HRESULT WINAPI HTMLElement_get_id(IHTMLElement *iface, BSTR *p)
451 {
452 HTMLElement *This = impl_from_IHTMLElement(iface);
453 nsAString id_str;
454 nsresult nsres;
455
456 TRACE("(%p)->(%p)\n", This, p);
457
458 if(!This->nselem) {
459 *p = NULL;
460 return S_OK;
461 }
462
463 nsAString_Init(&id_str, NULL);
464 nsres = nsIDOMHTMLElement_GetId(This->nselem, &id_str);
465 return return_nsstr(nsres, &id_str, p);
466 }
467
468 static HRESULT WINAPI HTMLElement_get_tagName(IHTMLElement *iface, BSTR *p)
469 {
470 HTMLElement *This = impl_from_IHTMLElement(iface);
471 nsAString tag_str;
472 nsresult nsres;
473
474 TRACE("(%p)->(%p)\n", This, p);
475
476 if(!This->nselem) {
477 static const WCHAR comment_tagW[] = {'!',0};
478
479 WARN("NULL nselem, assuming comment\n");
480
481 *p = SysAllocString(comment_tagW);
482 return *p ? S_OK : E_OUTOFMEMORY;
483 }
484
485 nsAString_Init(&tag_str, NULL);
486 nsres = nsIDOMHTMLElement_GetTagName(This->nselem, &tag_str);
487 return return_nsstr(nsres, &tag_str, p);
488 }
489
490 static HRESULT WINAPI HTMLElement_get_parentElement(IHTMLElement *iface, IHTMLElement **p)
491 {
492 HTMLElement *This = impl_from_IHTMLElement(iface);
493 IHTMLDOMNode *node;
494 HRESULT hres;
495
496 TRACE("(%p)->(%p)\n", This, p);
497
498 hres = IHTMLDOMNode_get_parentNode(&This->node.IHTMLDOMNode_iface, &node);
499 if(FAILED(hres))
500 return hres;
501
502 hres = IHTMLDOMNode_QueryInterface(node, &IID_IHTMLElement, (void**)p);
503 IHTMLDOMNode_Release(node);
504 if(FAILED(hres))
505 *p = NULL;
506
507 return S_OK;
508 }
509
510 static HRESULT WINAPI HTMLElement_get_style(IHTMLElement *iface, IHTMLStyle **p)
511 {
512 HTMLElement *This = impl_from_IHTMLElement(iface);
513
514 TRACE("(%p)->(%p)\n", This, p);
515
516 if(!This->style) {
517 HRESULT hres;
518
519 hres = HTMLStyle_Create(This, &This->style);
520 if(FAILED(hres))
521 return hres;
522 }
523
524 *p = &This->style->IHTMLStyle_iface;
525 IHTMLStyle_AddRef(*p);
526 return S_OK;
527 }
528
529 static HRESULT WINAPI HTMLElement_put_onhelp(IHTMLElement *iface, VARIANT v)
530 {
531 HTMLElement *This = impl_from_IHTMLElement(iface);
532 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
533 return E_NOTIMPL;
534 }
535
536 static HRESULT WINAPI HTMLElement_get_onhelp(IHTMLElement *iface, VARIANT *p)
537 {
538 HTMLElement *This = impl_from_IHTMLElement(iface);
539 FIXME("(%p)->(%p)\n", This, p);
540 return E_NOTIMPL;
541 }
542
543 static HRESULT WINAPI HTMLElement_put_onclick(IHTMLElement *iface, VARIANT v)
544 {
545 HTMLElement *This = impl_from_IHTMLElement(iface);
546
547 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
548
549 return set_node_event(&This->node, EVENTID_CLICK, &v);
550 }
551
552 static HRESULT WINAPI HTMLElement_get_onclick(IHTMLElement *iface, VARIANT *p)
553 {
554 HTMLElement *This = impl_from_IHTMLElement(iface);
555
556 TRACE("(%p)->(%p)\n", This, p);
557
558 return get_node_event(&This->node, EVENTID_CLICK, p);
559 }
560
561 static HRESULT WINAPI HTMLElement_put_ondblclick(IHTMLElement *iface, VARIANT v)
562 {
563 HTMLElement *This = impl_from_IHTMLElement(iface);
564
565 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
566
567 return set_node_event(&This->node, EVENTID_DBLCLICK, &v);
568 }
569
570 static HRESULT WINAPI HTMLElement_get_ondblclick(IHTMLElement *iface, VARIANT *p)
571 {
572 HTMLElement *This = impl_from_IHTMLElement(iface);
573
574 TRACE("(%p)->(%p)\n", This, p);
575
576 return get_node_event(&This->node, EVENTID_DBLCLICK, p);
577 }
578
579 static HRESULT WINAPI HTMLElement_put_onkeydown(IHTMLElement *iface, VARIANT v)
580 {
581 HTMLElement *This = impl_from_IHTMLElement(iface);
582
583 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
584
585 return set_node_event(&This->node, EVENTID_KEYDOWN, &v);
586 }
587
588 static HRESULT WINAPI HTMLElement_get_onkeydown(IHTMLElement *iface, VARIANT *p)
589 {
590 HTMLElement *This = impl_from_IHTMLElement(iface);
591
592 TRACE("(%p)->(%p)\n", This, p);
593
594 return get_node_event(&This->node, EVENTID_KEYDOWN, p);
595 }
596
597 static HRESULT WINAPI HTMLElement_put_onkeyup(IHTMLElement *iface, VARIANT v)
598 {
599 HTMLElement *This = impl_from_IHTMLElement(iface);
600
601 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
602
603 return set_node_event(&This->node, EVENTID_KEYUP, &v);
604 }
605
606 static HRESULT WINAPI HTMLElement_get_onkeyup(IHTMLElement *iface, VARIANT *p)
607 {
608 HTMLElement *This = impl_from_IHTMLElement(iface);
609 FIXME("(%p)->(%p)\n", This, p);
610 return E_NOTIMPL;
611 }
612
613 static HRESULT WINAPI HTMLElement_put_onkeypress(IHTMLElement *iface, VARIANT v)
614 {
615 HTMLElement *This = impl_from_IHTMLElement(iface);
616
617 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
618
619 return set_node_event(&This->node, EVENTID_KEYPRESS, &v);
620 }
621
622 static HRESULT WINAPI HTMLElement_get_onkeypress(IHTMLElement *iface, VARIANT *p)
623 {
624 HTMLElement *This = impl_from_IHTMLElement(iface);
625
626 TRACE("(%p)->(%p)\n", This, p);
627
628 return get_node_event(&This->node, EVENTID_KEYPRESS, p);
629 }
630
631 static HRESULT WINAPI HTMLElement_put_onmouseout(IHTMLElement *iface, VARIANT v)
632 {
633 HTMLElement *This = impl_from_IHTMLElement(iface);
634
635 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
636
637 return set_node_event(&This->node, EVENTID_MOUSEOUT, &v);
638 }
639
640 static HRESULT WINAPI HTMLElement_get_onmouseout(IHTMLElement *iface, VARIANT *p)
641 {
642 HTMLElement *This = impl_from_IHTMLElement(iface);
643
644 TRACE("(%p)->(%p)\n", This, p);
645
646 return get_node_event(&This->node, EVENTID_MOUSEOUT, p);
647 }
648
649 static HRESULT WINAPI HTMLElement_put_onmouseover(IHTMLElement *iface, VARIANT v)
650 {
651 HTMLElement *This = impl_from_IHTMLElement(iface);
652
653 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
654
655 return set_node_event(&This->node, EVENTID_MOUSEOVER, &v);
656 }
657
658 static HRESULT WINAPI HTMLElement_get_onmouseover(IHTMLElement *iface, VARIANT *p)
659 {
660 HTMLElement *This = impl_from_IHTMLElement(iface);
661
662 TRACE("(%p)->(%p)\n", This, p);
663
664 return get_node_event(&This->node, EVENTID_MOUSEOVER, p);
665 }
666
667 static HRESULT WINAPI HTMLElement_put_onmousemove(IHTMLElement *iface, VARIANT v)
668 {
669 HTMLElement *This = impl_from_IHTMLElement(iface);
670
671 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
672
673 return set_node_event(&This->node, EVENTID_MOUSEMOVE, &v);
674 }
675
676 static HRESULT WINAPI HTMLElement_get_onmousemove(IHTMLElement *iface, VARIANT *p)
677 {
678 HTMLElement *This = impl_from_IHTMLElement(iface);
679
680 TRACE("(%p)->(%p)\n", This, p);
681
682 return get_node_event(&This->node, EVENTID_MOUSEMOVE, p);
683 }
684
685 static HRESULT WINAPI HTMLElement_put_onmousedown(IHTMLElement *iface, VARIANT v)
686 {
687 HTMLElement *This = impl_from_IHTMLElement(iface);
688
689 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
690
691 return set_node_event(&This->node, EVENTID_MOUSEDOWN, &v);
692 }
693
694 static HRESULT WINAPI HTMLElement_get_onmousedown(IHTMLElement *iface, VARIANT *p)
695 {
696 HTMLElement *This = impl_from_IHTMLElement(iface);
697
698 TRACE("(%p)->(%p)\n", This, p);
699
700 return get_node_event(&This->node, EVENTID_MOUSEDOWN, p);
701 }
702
703 static HRESULT WINAPI HTMLElement_put_onmouseup(IHTMLElement *iface, VARIANT v)
704 {
705 HTMLElement *This = impl_from_IHTMLElement(iface);
706
707 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
708
709 return set_node_event(&This->node, EVENTID_MOUSEUP, &v);
710 }
711
712 static HRESULT WINAPI HTMLElement_get_onmouseup(IHTMLElement *iface, VARIANT *p)
713 {
714 HTMLElement *This = impl_from_IHTMLElement(iface);
715
716 TRACE("(%p)->(%p)\n", This, p);
717
718 return get_node_event(&This->node, EVENTID_MOUSEUP, p);
719 }
720
721 static HRESULT WINAPI HTMLElement_get_document(IHTMLElement *iface, IDispatch **p)
722 {
723 HTMLElement *This = impl_from_IHTMLElement(iface);
724
725 TRACE("(%p)->(%p)\n", This, p);
726
727 if(!p)
728 return E_POINTER;
729
730 if(This->node.vtbl->get_document)
731 return This->node.vtbl->get_document(&This->node, p);
732
733 *p = (IDispatch*)&This->node.doc->basedoc.IHTMLDocument2_iface;
734 IDispatch_AddRef(*p);
735 return S_OK;
736 }
737
738 static const WCHAR titleW[] = {'t','i','t','l','e',0};
739
740 static HRESULT WINAPI HTMLElement_put_title(IHTMLElement *iface, BSTR v)
741 {
742 HTMLElement *This = impl_from_IHTMLElement(iface);
743 nsAString title_str;
744 nsresult nsres;
745
746 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
747
748 if(!This->nselem) {
749 VARIANT *var;
750 HRESULT hres;
751
752 hres = dispex_get_dprop_ref(&This->node.dispex, titleW, TRUE, &var);
753 if(FAILED(hres))
754 return hres;
755
756 VariantClear(var);
757 V_VT(var) = VT_BSTR;
758 V_BSTR(var) = v ? SysAllocString(v) : NULL;
759 return S_OK;
760 }
761
762 nsAString_InitDepend(&title_str, v);
763 nsres = nsIDOMHTMLElement_SetTitle(This->nselem, &title_str);
764 nsAString_Finish(&title_str);
765 if(NS_FAILED(nsres))
766 ERR("SetTitle failed: %08x\n", nsres);
767
768 return S_OK;
769 }
770
771 static HRESULT WINAPI HTMLElement_get_title(IHTMLElement *iface, BSTR *p)
772 {
773 HTMLElement *This = impl_from_IHTMLElement(iface);
774 nsAString title_str;
775 nsresult nsres;
776
777 TRACE("(%p)->(%p)\n", This, p);
778
779 if(!This->nselem) {
780 VARIANT *var;
781 HRESULT hres;
782
783 hres = dispex_get_dprop_ref(&This->node.dispex, titleW, FALSE, &var);
784 if(hres == DISP_E_UNKNOWNNAME) {
785 *p = NULL;
786 }else if(V_VT(var) != VT_BSTR) {
787 FIXME("title = %s\n", debugstr_variant(var));
788 return E_FAIL;
789 }else {
790 *p = V_BSTR(var) ? SysAllocString(V_BSTR(var)) : NULL;
791 }
792
793 return S_OK;
794 }
795
796 nsAString_Init(&title_str, NULL);
797 nsres = nsIDOMHTMLElement_GetTitle(This->nselem, &title_str);
798 return return_nsstr(nsres, &title_str, p);
799 }
800
801 static HRESULT WINAPI HTMLElement_put_language(IHTMLElement *iface, BSTR v)
802 {
803 HTMLElement *This = impl_from_IHTMLElement(iface);
804 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
805 return E_NOTIMPL;
806 }
807
808 static HRESULT WINAPI HTMLElement_get_language(IHTMLElement *iface, BSTR *p)
809 {
810 HTMLElement *This = impl_from_IHTMLElement(iface);
811 FIXME("(%p)->(%p)\n", This, p);
812 return E_NOTIMPL;
813 }
814
815 static HRESULT WINAPI HTMLElement_put_onselectstart(IHTMLElement *iface, VARIANT v)
816 {
817 HTMLElement *This = impl_from_IHTMLElement(iface);
818
819 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
820
821 return set_node_event(&This->node, EVENTID_SELECTSTART, &v);
822 }
823
824 static HRESULT WINAPI HTMLElement_get_onselectstart(IHTMLElement *iface, VARIANT *p)
825 {
826 HTMLElement *This = impl_from_IHTMLElement(iface);
827
828 TRACE("(%p)->(%p)\n", This, p);
829
830 return get_node_event(&This->node, EVENTID_SELECTSTART, p);
831 }
832
833 static HRESULT WINAPI HTMLElement_scrollIntoView(IHTMLElement *iface, VARIANT varargStart)
834 {
835 HTMLElement *This = impl_from_IHTMLElement(iface);
836 cpp_bool start = TRUE;
837 nsresult nsres;
838
839 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varargStart));
840
841 switch(V_VT(&varargStart)) {
842 case VT_EMPTY:
843 case VT_ERROR:
844 break;
845 case VT_BOOL:
846 start = V_BOOL(&varargStart) != VARIANT_FALSE;
847 break;
848 default:
849 FIXME("Unsupported argument %s\n", debugstr_variant(&varargStart));
850 }
851
852 if(!This->nselem) {
853 FIXME("Unsupported for comments\n");
854 return E_NOTIMPL;
855 }
856
857 nsres = nsIDOMHTMLElement_ScrollIntoView(This->nselem, start, 1);
858 assert(nsres == NS_OK);
859
860 return S_OK;
861 }
862
863 static HRESULT WINAPI HTMLElement_contains(IHTMLElement *iface, IHTMLElement *pChild,
864 VARIANT_BOOL *pfResult)
865 {
866 HTMLElement *This = impl_from_IHTMLElement(iface);
867 cpp_bool result = FALSE;
868
869 TRACE("(%p)->(%p %p)\n", This, pChild, pfResult);
870
871 if(pChild) {
872 HTMLElement *child;
873 nsresult nsres;
874
875 child = unsafe_impl_from_IHTMLElement(pChild);
876 if(!child) {
877 ERR("not our element\n");
878 return E_FAIL;
879 }
880
881 nsres = nsIDOMNode_Contains(This->node.nsnode, child->node.nsnode, &result);
882 assert(nsres == NS_OK);
883 }
884
885 *pfResult = result ? VARIANT_TRUE : VARIANT_FALSE;
886 return S_OK;
887 }
888
889 static HRESULT WINAPI HTMLElement_get_sourceIndex(IHTMLElement *iface, LONG *p)
890 {
891 HTMLElement *This = impl_from_IHTMLElement(iface);
892
893 TRACE("(%p)->(%p)\n", This, p);
894
895 return get_elem_source_index(This, p);
896 }
897
898 static HRESULT WINAPI HTMLElement_get_recordNumber(IHTMLElement *iface, VARIANT *p)
899 {
900 HTMLElement *This = impl_from_IHTMLElement(iface);
901 FIXME("(%p)->(%p)\n", This, p);
902 return E_NOTIMPL;
903 }
904
905 static HRESULT WINAPI HTMLElement_put_lang(IHTMLElement *iface, BSTR v)
906 {
907 HTMLElement *This = impl_from_IHTMLElement(iface);
908 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
909 return E_NOTIMPL;
910 }
911
912 static HRESULT WINAPI HTMLElement_get_lang(IHTMLElement *iface, BSTR *p)
913 {
914 HTMLElement *This = impl_from_IHTMLElement(iface);
915 FIXME("(%p)->(%p)\n", This, p);
916 return E_NOTIMPL;
917 }
918
919 static HRESULT WINAPI HTMLElement_get_offsetLeft(IHTMLElement *iface, LONG *p)
920 {
921 HTMLElement *This = impl_from_IHTMLElement(iface);
922 nsresult nsres;
923
924 TRACE("(%p)->(%p)\n", This, p);
925
926 nsres = nsIDOMHTMLElement_GetOffsetLeft(This->nselem, p);
927 if(NS_FAILED(nsres)) {
928 ERR("GetOffsetLeft failed: %08x\n", nsres);
929 return E_FAIL;
930 }
931
932 return S_OK;
933 }
934
935 static HRESULT WINAPI HTMLElement_get_offsetTop(IHTMLElement *iface, LONG *p)
936 {
937 HTMLElement *This = impl_from_IHTMLElement(iface);
938 nsresult nsres;
939
940 TRACE("(%p)->(%p)\n", This, p);
941
942 nsres = nsIDOMHTMLElement_GetOffsetTop(This->nselem, p);
943 if(NS_FAILED(nsres)) {
944 ERR("GetOffsetTop failed: %08x\n", nsres);
945 return E_FAIL;
946 }
947
948 return S_OK;
949 }
950
951 static HRESULT WINAPI HTMLElement_get_offsetWidth(IHTMLElement *iface, LONG *p)
952 {
953 HTMLElement *This = impl_from_IHTMLElement(iface);
954 nsresult nsres;
955
956 TRACE("(%p)->(%p)\n", This, p);
957
958 nsres = nsIDOMHTMLElement_GetOffsetWidth(This->nselem, p);
959 if(NS_FAILED(nsres)) {
960 ERR("GetOffsetWidth failed: %08x\n", nsres);
961 return E_FAIL;
962 }
963
964 return S_OK;
965 }
966
967 static HRESULT WINAPI HTMLElement_get_offsetHeight(IHTMLElement *iface, LONG *p)
968 {
969 HTMLElement *This = impl_from_IHTMLElement(iface);
970 nsresult nsres;
971
972 TRACE("(%p)->(%p)\n", This, p);
973
974 nsres = nsIDOMHTMLElement_GetOffsetHeight(This->nselem, p);
975 if(NS_FAILED(nsres)) {
976 ERR("GetOffsetHeight failed: %08x\n", nsres);
977 return E_FAIL;
978 }
979
980 return S_OK;
981 }
982
983 static HRESULT WINAPI HTMLElement_get_offsetParent(IHTMLElement *iface, IHTMLElement **p)
984 {
985 HTMLElement *This = impl_from_IHTMLElement(iface);
986 nsIDOMElement *nsparent;
987 nsresult nsres;
988 HRESULT hres;
989
990 TRACE("(%p)->(%p)\n", This, p);
991
992 nsres = nsIDOMHTMLElement_GetOffsetParent(This->nselem, &nsparent);
993 if(NS_FAILED(nsres)) {
994 ERR("GetOffsetParent failed: %08x\n", nsres);
995 return E_FAIL;
996 }
997
998 if(nsparent) {
999 HTMLDOMNode *node;
1000
1001 hres = get_node(This->node.doc, (nsIDOMNode*)nsparent, TRUE, &node);
1002 nsIDOMElement_Release(nsparent);
1003 if(FAILED(hres))
1004 return hres;
1005
1006 hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p);
1007 node_release(node);
1008 }else {
1009 *p = NULL;
1010 hres = S_OK;
1011 }
1012
1013 return hres;
1014 }
1015
1016 static HRESULT WINAPI HTMLElement_put_innerHTML(IHTMLElement *iface, BSTR v)
1017 {
1018 HTMLElement *This = impl_from_IHTMLElement(iface);
1019 nsAString html_str;
1020 nsresult nsres;
1021
1022 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1023
1024 if(!This->nselem) {
1025 FIXME("NULL nselem\n");
1026 return E_NOTIMPL;
1027 }
1028
1029 nsAString_InitDepend(&html_str, v);
1030 nsres = nsIDOMHTMLElement_SetInnerHTML(This->nselem, &html_str);
1031 nsAString_Finish(&html_str);
1032 if(NS_FAILED(nsres)) {
1033 FIXME("SetInnerHtml failed %08x\n", nsres);
1034 return E_FAIL;
1035 }
1036
1037 return S_OK;
1038 }
1039
1040 static HRESULT WINAPI HTMLElement_get_innerHTML(IHTMLElement *iface, BSTR *p)
1041 {
1042 HTMLElement *This = impl_from_IHTMLElement(iface);
1043 nsAString html_str;
1044 nsresult nsres;
1045
1046 TRACE("(%p)->(%p)\n", This, p);
1047
1048 if(!This->nselem) {
1049 FIXME("NULL nselem\n");
1050 return E_NOTIMPL;
1051 }
1052
1053 nsAString_Init(&html_str, NULL);
1054 nsres = nsIDOMHTMLElement_GetInnerHTML(This->nselem, &html_str);
1055 return return_nsstr(nsres, &html_str, p);
1056 }
1057
1058 static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v)
1059 {
1060 HTMLElement *This = impl_from_IHTMLElement(iface);
1061 nsIDOMNode *nschild, *tmp;
1062 nsIDOMText *text_node;
1063 nsAString text_str;
1064 nsresult nsres;
1065
1066 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1067
1068 while(1) {
1069 nsres = nsIDOMHTMLElement_GetLastChild(This->nselem, &nschild);
1070 if(NS_FAILED(nsres)) {
1071 ERR("GetLastChild failed: %08x\n", nsres);
1072 return E_FAIL;
1073 }
1074 if(!nschild)
1075 break;
1076
1077 nsres = nsIDOMHTMLElement_RemoveChild(This->nselem, nschild, &tmp);
1078 nsIDOMNode_Release(nschild);
1079 if(NS_FAILED(nsres)) {
1080 ERR("RemoveChild failed: %08x\n", nsres);
1081 return E_FAIL;
1082 }
1083 nsIDOMNode_Release(tmp);
1084 }
1085
1086 nsAString_InitDepend(&text_str, v);
1087 nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->nsdoc, &text_str, &text_node);
1088 nsAString_Finish(&text_str);
1089 if(NS_FAILED(nsres)) {
1090 ERR("CreateTextNode failed: %08x\n", nsres);
1091 return E_FAIL;
1092 }
1093
1094 nsres = nsIDOMHTMLElement_AppendChild(This->nselem, (nsIDOMNode*)text_node, &tmp);
1095 if(NS_FAILED(nsres)) {
1096 ERR("AppendChild failed: %08x\n", nsres);
1097 return E_FAIL;
1098 }
1099
1100 nsIDOMNode_Release(tmp);
1101 return S_OK;
1102 }
1103
1104 static HRESULT WINAPI HTMLElement_get_innerText(IHTMLElement *iface, BSTR *p)
1105 {
1106 HTMLElement *This = impl_from_IHTMLElement(iface);
1107
1108 TRACE("(%p)->(%p)\n", This, p);
1109
1110 return get_node_text(&This->node, p);
1111 }
1112
1113 static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
1114 {
1115 HTMLElement *This = impl_from_IHTMLElement(iface);
1116
1117 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1118
1119 return replace_node_by_html(This->node.doc->nsdoc, This->node.nsnode, v);
1120 }
1121
1122 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
1123 {
1124 HTMLElement *This = impl_from_IHTMLElement(iface);
1125 nsAString html_str;
1126 HRESULT hres;
1127
1128 WARN("(%p)->(%p) semi-stub\n", This, p);
1129
1130 nsAString_Init(&html_str, NULL);
1131 hres = nsnode_to_nsstring(This->node.nsnode, &html_str);
1132 if(SUCCEEDED(hres)) {
1133 const PRUnichar *html;
1134
1135 nsAString_GetData(&html_str, &html);
1136 *p = SysAllocString(html);
1137 if(!*p)
1138 hres = E_OUTOFMEMORY;
1139 }
1140
1141 nsAString_Finish(&html_str);
1142
1143 TRACE("ret %s\n", debugstr_w(*p));
1144 return hres;
1145 }
1146
1147 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
1148 {
1149 HTMLElement *This = impl_from_IHTMLElement(iface);
1150 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1151 return E_NOTIMPL;
1152 }
1153
1154 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
1155 {
1156 HTMLElement *This = impl_from_IHTMLElement(iface);
1157 FIXME("(%p)->(%p)\n", This, p);
1158 return E_NOTIMPL;
1159 }
1160
1161 HRESULT insert_adjacent_node(HTMLElement *This, const WCHAR *where, nsIDOMNode *nsnode, HTMLDOMNode **ret_node)
1162 {
1163 nsIDOMNode *ret_nsnode;
1164 nsresult nsres;
1165 HRESULT hres = S_OK;
1166
1167 static const WCHAR beforebeginW[] = {'b','e','f','o','r','e','b','e','g','i','n',0};
1168 static const WCHAR afterbeginW[] = {'a','f','t','e','r','b','e','g','i','n',0};
1169 static const WCHAR beforeendW[] = {'b','e','f','o','r','e','e','n','d',0};
1170 static const WCHAR afterendW[] = {'a','f','t','e','r','e','n','d',0};
1171
1172 if (!strcmpiW(where, beforebeginW)) {
1173 nsIDOMNode *parent;
1174
1175 nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &parent);
1176 if(NS_FAILED(nsres))
1177 return E_FAIL;
1178
1179 if(!parent)
1180 return E_INVALIDARG;
1181
1182 nsres = nsIDOMNode_InsertBefore(parent, nsnode, This->node.nsnode, &ret_nsnode);
1183 nsIDOMNode_Release(parent);
1184 }else if(!strcmpiW(where, afterbeginW)) {
1185 nsIDOMNode *first_child;
1186
1187 nsres = nsIDOMNode_GetFirstChild(This->node.nsnode, &first_child);
1188 if(NS_FAILED(nsres))
1189 return E_FAIL;
1190
1191 nsres = nsIDOMNode_InsertBefore(This->node.nsnode, nsnode, first_child, &ret_nsnode);
1192 if(NS_FAILED(nsres))
1193 return E_FAIL;
1194
1195 if (first_child)
1196 nsIDOMNode_Release(first_child);
1197 }else if (!strcmpiW(where, beforeendW)) {
1198 nsres = nsIDOMNode_AppendChild(This->node.nsnode, nsnode, &ret_nsnode);
1199 }else if (!strcmpiW(where, afterendW)) {
1200 nsIDOMNode *next_sibling, *parent;
1201
1202 nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &parent);
1203 if(NS_FAILED(nsres))
1204 return E_FAIL;
1205 if(!parent)
1206 return E_INVALIDARG;
1207
1208 nsres = nsIDOMNode_GetNextSibling(This->node.nsnode, &next_sibling);
1209 if(NS_SUCCEEDED(nsres)) {
1210 if(next_sibling) {
1211 nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &ret_nsnode);
1212 nsIDOMNode_Release(next_sibling);
1213 }else {
1214 nsres = nsIDOMNode_AppendChild(parent, nsnode, &ret_nsnode);
1215 }
1216 }
1217
1218 nsIDOMNode_Release(parent);
1219 }else {
1220 ERR("invalid where: %s\n", debugstr_w(where));
1221 return E_INVALIDARG;
1222 }
1223
1224 if (NS_FAILED(nsres))
1225 return E_FAIL;
1226
1227 if(ret_node)
1228 hres = get_node(This->node.doc, ret_nsnode, TRUE, ret_node);
1229 nsIDOMNode_Release(ret_nsnode);
1230 return hres;
1231 }
1232
1233 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
1234 BSTR html)
1235 {
1236 HTMLElement *This = impl_from_IHTMLElement(iface);
1237 nsIDOMRange *range;
1238 nsIDOMNode *nsnode;
1239 nsAString ns_html;
1240 nsresult nsres;
1241 HRESULT hr;
1242
1243 TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
1244
1245 if(!This->node.doc->nsdoc) {
1246 WARN("NULL nsdoc\n");
1247 return E_UNEXPECTED;
1248 }
1249
1250 nsres = nsIDOMHTMLDocument_CreateRange(This->node.doc->nsdoc, &range);
1251 if(NS_FAILED(nsres))
1252 {
1253 ERR("CreateRange failed: %08x\n", nsres);
1254 return E_FAIL;
1255 }
1256
1257 nsIDOMRange_SetStartBefore(range, This->node.nsnode);
1258
1259 nsAString_InitDepend(&ns_html, html);
1260 nsres = nsIDOMRange_CreateContextualFragment(range, &ns_html, (nsIDOMDocumentFragment **)&nsnode);
1261 nsAString_Finish(&ns_html);
1262 nsIDOMRange_Release(range);
1263
1264 if(NS_FAILED(nsres) || !nsnode)
1265 {
1266 ERR("CreateTextNode failed: %08x\n", nsres);
1267 return E_FAIL;
1268 }
1269
1270 hr = insert_adjacent_node(This, where, nsnode, NULL);
1271 nsIDOMNode_Release(nsnode);
1272 return hr;
1273 }
1274
1275 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
1276 BSTR text)
1277 {
1278 HTMLElement *This = impl_from_IHTMLElement(iface);
1279 nsIDOMNode *nsnode;
1280 nsAString ns_text;
1281 nsresult nsres;
1282 HRESULT hr;
1283
1284 TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
1285
1286 if(!This->node.doc->nsdoc) {
1287 WARN("NULL nsdoc\n");
1288 return E_UNEXPECTED;
1289 }
1290
1291
1292 nsAString_InitDepend(&ns_text, text);
1293 nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->nsdoc, &ns_text, (nsIDOMText **)&nsnode);
1294 nsAString_Finish(&ns_text);
1295
1296 if(NS_FAILED(nsres) || !nsnode)
1297 {
1298 ERR("CreateTextNode failed: %08x\n", nsres);
1299 return E_FAIL;
1300 }
1301
1302 hr = insert_adjacent_node(This, where, nsnode, NULL);
1303 nsIDOMNode_Release(nsnode);
1304
1305 return hr;
1306 }
1307
1308 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
1309 {
1310 HTMLElement *This = impl_from_IHTMLElement(iface);
1311 FIXME("(%p)->(%p)\n", This, p);
1312 return E_NOTIMPL;
1313 }
1314
1315 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *p)
1316 {
1317 HTMLElement *This = impl_from_IHTMLElement(iface);
1318 FIXME("(%p)->(%p)\n", This, p);
1319 return E_NOTIMPL;
1320 }
1321
1322 static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface)
1323 {
1324 HTMLElement *This = impl_from_IHTMLElement(iface);
1325
1326 TRACE("(%p)\n", This);
1327
1328 return call_fire_event(&This->node, EVENTID_CLICK);
1329 }
1330
1331 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
1332 IHTMLFiltersCollection **p)
1333 {
1334 HTMLElement *This = impl_from_IHTMLElement(iface);
1335 TRACE("(%p)->(%p)\n", This, p);
1336
1337 if(!p)
1338 return E_POINTER;
1339
1340 *p = HTMLFiltersCollection_Create();
1341
1342 return S_OK;
1343 }
1344
1345 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
1346 {
1347 HTMLElement *This = impl_from_IHTMLElement(iface);
1348 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1349 return E_NOTIMPL;
1350 }
1351
1352 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
1353 {
1354 HTMLElement *This = impl_from_IHTMLElement(iface);
1355 FIXME("(%p)->(%p)\n", This, p);
1356 return E_NOTIMPL;
1357 }
1358
1359 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
1360 {
1361 HTMLElement *This = impl_from_IHTMLElement(iface);
1362 FIXME("(%p)->(%p)\n", This, String);
1363 return E_NOTIMPL;
1364 }
1365
1366 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
1367 {
1368 HTMLElement *This = impl_from_IHTMLElement(iface);
1369 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1370 return E_NOTIMPL;
1371 }
1372
1373 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
1374 {
1375 HTMLElement *This = impl_from_IHTMLElement(iface);
1376 FIXME("(%p)->(%p)\n", This, p);
1377 return E_NOTIMPL;
1378 }
1379
1380 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
1381 {
1382 HTMLElement *This = impl_from_IHTMLElement(iface);
1383 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1384 return E_NOTIMPL;
1385 }
1386
1387 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
1388 {
1389 HTMLElement *This = impl_from_IHTMLElement(iface);
1390 FIXME("(%p)->(%p)\n", This, p);
1391 return E_NOTIMPL;
1392 }
1393
1394 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
1395 {
1396 HTMLElement *This = impl_from_IHTMLElement(iface);
1397 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1398 return E_NOTIMPL;
1399 }
1400
1401 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
1402 {
1403 HTMLElement *This = impl_from_IHTMLElement(iface);
1404 FIXME("(%p)->(%p)\n", This, p);
1405 return E_NOTIMPL;
1406 }
1407
1408 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
1409 {
1410 HTMLElement *This = impl_from_IHTMLElement(iface);
1411 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1412 return E_NOTIMPL;
1413 }
1414
1415 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
1416 {
1417 HTMLElement *This = impl_from_IHTMLElement(iface);
1418 FIXME("(%p)->(%p)\n", This, p);
1419 return E_NOTIMPL;
1420 }
1421
1422 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
1423 {
1424 HTMLElement *This = impl_from_IHTMLElement(iface);
1425 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1426 return E_NOTIMPL;
1427 }
1428
1429 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
1430 {
1431 HTMLElement *This = impl_from_IHTMLElement(iface);
1432 FIXME("(%p)->(%p)\n", This, p);
1433 return E_NOTIMPL;
1434 }
1435
1436 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
1437 {
1438 HTMLElement *This = impl_from_IHTMLElement(iface);
1439 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1440 return E_NOTIMPL;
1441 }
1442
1443 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
1444 {
1445 HTMLElement *This = impl_from_IHTMLElement(iface);
1446 FIXME("(%p)->(%p)\n", This, p);
1447 return E_NOTIMPL;
1448 }
1449
1450 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
1451 {
1452 HTMLElement *This = impl_from_IHTMLElement(iface);
1453
1454 FIXME("(%p)->(%s) semi-stub\n", This, debugstr_variant(&v));
1455
1456 return set_node_event(&This->node, EVENTID_DATAAVAILABLE, &v);
1457 }
1458
1459 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
1460 {
1461 HTMLElement *This = impl_from_IHTMLElement(iface);
1462
1463 TRACE("(%p)->(%p)\n", This, p);
1464
1465 return get_node_event(&This->node, EVENTID_DATAAVAILABLE, p);
1466 }
1467
1468 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
1469 {
1470 HTMLElement *This = impl_from_IHTMLElement(iface);
1471 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1472 return E_NOTIMPL;
1473 }
1474
1475 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
1476 {
1477 HTMLElement *This = impl_from_IHTMLElement(iface);
1478 FIXME("(%p)->(%p)\n", This, p);
1479 return E_NOTIMPL;
1480 }
1481
1482 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
1483 {
1484 HTMLElement *This = impl_from_IHTMLElement(iface);
1485 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1486 return E_NOTIMPL;
1487 }
1488
1489 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
1490 {
1491 HTMLElement *This = impl_from_IHTMLElement(iface);
1492 FIXME("(%p)->(%p)\n", This, p);
1493 return E_NOTIMPL;
1494 }
1495
1496 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
1497 {
1498 HTMLElement *This = impl_from_IHTMLElement(iface);
1499 nsIDOMNodeList *nsnode_list;
1500 nsresult nsres;
1501
1502 TRACE("(%p)->(%p)\n", This, p);
1503
1504 nsres = nsIDOMNode_GetChildNodes(This->node.nsnode, &nsnode_list);
1505 if(NS_FAILED(nsres)) {
1506 ERR("GetChildNodes failed: %08x\n", nsres);
1507 return E_FAIL;
1508 }
1509
1510 *p = (IDispatch*)create_collection_from_nodelist(This->node.doc, nsnode_list);
1511
1512 nsIDOMNodeList_Release(nsnode_list);
1513 return S_OK;
1514 }
1515
1516 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
1517 {
1518 HTMLElement *This = impl_from_IHTMLElement(iface);
1519
1520 TRACE("(%p)->(%p)\n", This, p);
1521
1522 *p = (IDispatch*)create_all_collection(&This->node, FALSE);
1523 return S_OK;
1524 }
1525
1526 static const IHTMLElementVtbl HTMLElementVtbl = {
1527 HTMLElement_QueryInterface,
1528 HTMLElement_AddRef,
1529 HTMLElement_Release,
1530 HTMLElement_GetTypeInfoCount,
1531 HTMLElement_GetTypeInfo,
1532 HTMLElement_GetIDsOfNames,
1533 HTMLElement_Invoke,
1534 HTMLElement_setAttribute,
1535 HTMLElement_getAttribute,
1536 HTMLElement_removeAttribute,
1537 HTMLElement_put_className,
1538 HTMLElement_get_className,
1539 HTMLElement_put_id,
1540 HTMLElement_get_id,
1541 HTMLElement_get_tagName,
1542 HTMLElement_get_parentElement,
1543 HTMLElement_get_style,
1544 HTMLElement_put_onhelp,
1545 HTMLElement_get_onhelp,
1546 HTMLElement_put_onclick,
1547 HTMLElement_get_onclick,
1548 HTMLElement_put_ondblclick,
1549 HTMLElement_get_ondblclick,
1550 HTMLElement_put_onkeydown,
1551 HTMLElement_get_onkeydown,
1552 HTMLElement_put_onkeyup,
1553 HTMLElement_get_onkeyup,
1554 HTMLElement_put_onkeypress,
1555 HTMLElement_get_onkeypress,
1556 HTMLElement_put_onmouseout,
1557 HTMLElement_get_onmouseout,
1558 HTMLElement_put_onmouseover,
1559 HTMLElement_get_onmouseover,
1560 HTMLElement_put_onmousemove,
1561 HTMLElement_get_onmousemove,
1562 HTMLElement_put_onmousedown,
1563 HTMLElement_get_onmousedown,
1564 HTMLElement_put_onmouseup,
1565 HTMLElement_get_onmouseup,
1566 HTMLElement_get_document,
1567 HTMLElement_put_title,
1568 HTMLElement_get_title,
1569 HTMLElement_put_language,
1570 HTMLElement_get_language,
1571 HTMLElement_put_onselectstart,
1572 HTMLElement_get_onselectstart,
1573 HTMLElement_scrollIntoView,
1574 HTMLElement_contains,
1575 HTMLElement_get_sourceIndex,
1576 HTMLElement_get_recordNumber,
1577 HTMLElement_put_lang,
1578 HTMLElement_get_lang,
1579 HTMLElement_get_offsetLeft,
1580 HTMLElement_get_offsetTop,
1581 HTMLElement_get_offsetWidth,
1582 HTMLElement_get_offsetHeight,
1583 HTMLElement_get_offsetParent,
1584 HTMLElement_put_innerHTML,
1585 HTMLElement_get_innerHTML,
1586 HTMLElement_put_innerText,
1587 HTMLElement_get_innerText,
1588 HTMLElement_put_outerHTML,
1589 HTMLElement_get_outerHTML,
1590 HTMLElement_put_outerText,
1591 HTMLElement_get_outerText,
1592 HTMLElement_insertAdjacentHTML,
1593 HTMLElement_insertAdjacentText,
1594 HTMLElement_get_parentTextEdit,
1595 HTMLElement_get_isTextEdit,
1596 HTMLElement_click,
1597 HTMLElement_get_filters,
1598 HTMLElement_put_ondragstart,
1599 HTMLElement_get_ondragstart,
1600 HTMLElement_toString,
1601 HTMLElement_put_onbeforeupdate,
1602 HTMLElement_get_onbeforeupdate,
1603 HTMLElement_put_onafterupdate,
1604 HTMLElement_get_onafterupdate,
1605 HTMLElement_put_onerrorupdate,
1606 HTMLElement_get_onerrorupdate,
1607 HTMLElement_put_onrowexit,
1608 HTMLElement_get_onrowexit,
1609 HTMLElement_put_onrowenter,
1610 HTMLElement_get_onrowenter,
1611 HTMLElement_put_ondatasetchanged,
1612 HTMLElement_get_ondatasetchanged,
1613 HTMLElement_put_ondataavailable,
1614 HTMLElement_get_ondataavailable,
1615 HTMLElement_put_ondatasetcomplete,
1616 HTMLElement_get_ondatasetcomplete,
1617 HTMLElement_put_onfilterchange,
1618 HTMLElement_get_onfilterchange,
1619 HTMLElement_get_children,
1620 HTMLElement_get_all
1621 };
1622
1623 HTMLElement *unsafe_impl_from_IHTMLElement(IHTMLElement *iface)
1624 {
1625 return iface->lpVtbl == &HTMLElementVtbl ? impl_from_IHTMLElement(iface) : NULL;
1626 }
1627
1628 static inline HTMLElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
1629 {
1630 return CONTAINING_RECORD(iface, HTMLElement, node);
1631 }
1632
1633 HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1634 {
1635 HTMLElement *This = impl_from_HTMLDOMNode(iface);
1636
1637 if(IsEqualGUID(&IID_IUnknown, riid)) {
1638 *ppv = &This->IHTMLElement_iface;
1639 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1640 *ppv = &This->IHTMLElement_iface;
1641 }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
1642 *ppv = &This->IHTMLElement_iface;
1643 }else if(IsEqualGUID(&IID_IHTMLElement2, riid)) {
1644 *ppv = &This->IHTMLElement2_iface;
1645 }else if(IsEqualGUID(&IID_IHTMLElement3, riid)) {
1646 *ppv = &This->IHTMLElement3_iface;
1647 }else if(IsEqualGUID(&IID_IHTMLElement4, riid)) {
1648 *ppv = &This->IHTMLElement4_iface;
1649 }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1650 *ppv = &This->cp_container.IConnectionPointContainer_iface;
1651 }else {
1652 return HTMLDOMNode_QI(&This->node, riid, ppv);
1653 }
1654
1655 IUnknown_AddRef((IUnknown*)*ppv);
1656 return S_OK;
1657 }
1658
1659 void HTMLElement_destructor(HTMLDOMNode *iface)
1660 {
1661 HTMLElement *This = impl_from_HTMLDOMNode(iface);
1662
1663 ConnectionPointContainer_Destroy(&This->cp_container);
1664
1665 if(This->style) {
1666 This->style->elem = NULL;
1667 IHTMLStyle_Release(&This->style->IHTMLStyle_iface);
1668 }
1669 if(This->runtime_style) {
1670 This->runtime_style->elem = NULL;
1671 IHTMLStyle_Release(&This->runtime_style->IHTMLStyle_iface);
1672 }
1673 if(This->attrs) {
1674 HTMLDOMAttribute *attr;
1675
1676 LIST_FOR_EACH_ENTRY(attr, &This->attrs->attrs, HTMLDOMAttribute, entry)
1677 attr->elem = NULL;
1678
1679 This->attrs->elem = NULL;
1680 IHTMLAttributeCollection_Release(&This->attrs->IHTMLAttributeCollection_iface);
1681 }
1682
1683 heap_free(This->filter);
1684
1685 HTMLDOMNode_destructor(&This->node);
1686 }
1687
1688 HRESULT HTMLElement_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
1689 {
1690 HTMLElement *This = impl_from_HTMLDOMNode(iface);
1691 HTMLElement *new_elem;
1692 HRESULT hres;
1693
1694 hres = HTMLElement_Create(This->node.doc, nsnode, FALSE, &new_elem);
1695 if(FAILED(hres))
1696 return hres;
1697
1698 if(This->filter) {
1699 new_elem->filter = heap_strdupW(This->filter);
1700 if(!new_elem->filter) {
1701 IHTMLElement_Release(&This->IHTMLElement_iface);
1702 return E_OUTOFMEMORY;
1703 }
1704 }
1705
1706 *ret = &new_elem->node;
1707 return S_OK;
1708 }
1709
1710 HRESULT HTMLElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default)
1711 {
1712 HTMLElement *This = impl_from_HTMLDOMNode(iface);
1713
1714 switch(eid) {
1715 case EVENTID_KEYDOWN: {
1716 nsIDOMKeyEvent *key_event;
1717 nsresult nsres;
1718
1719 nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMKeyEvent, (void**)&key_event);
1720 if(NS_SUCCEEDED(nsres)) {
1721 UINT32 code = 0;
1722
1723 nsIDOMKeyEvent_GetKeyCode(key_event, &code);
1724
1725 switch(code) {
1726 case VK_F1: /* DOM_VK_F1 */
1727 TRACE("F1 pressed\n");
1728 fire_event(This->node.doc, EVENTID_HELP, TRUE, This->node.nsnode, NULL, NULL);
1729 *prevent_default = TRUE;
1730 }
1731
1732 nsIDOMKeyEvent_Release(key_event);
1733 }
1734 }
1735 }
1736
1737 return S_OK;
1738 }
1739
1740 cp_static_data_t HTMLElementEvents2_data = { HTMLElementEvents2_tid, NULL /* FIXME */, TRUE };
1741
1742 const cpc_entry_t HTMLElement_cpc[] = {
1743 HTMLELEMENT_CPC,
1744 {NULL}
1745 };
1746
1747 static const NodeImplVtbl HTMLElementImplVtbl = {
1748 HTMLElement_QI,
1749 HTMLElement_destructor,
1750 HTMLElement_cpc,
1751 HTMLElement_clone,
1752 HTMLElement_handle_event,
1753 HTMLElement_get_attr_col
1754 };
1755
1756 static inline HTMLElement *impl_from_DispatchEx(DispatchEx *iface)
1757 {
1758 return CONTAINING_RECORD(iface, HTMLElement, node.dispex);
1759 }
1760
1761 static HRESULT HTMLElement_get_dispid(DispatchEx *dispex, BSTR name,
1762 DWORD grfdex, DISPID *pid)
1763 {
1764 HTMLElement *This = impl_from_DispatchEx(dispex);
1765
1766 if(This->node.vtbl->get_dispid)
1767 return This->node.vtbl->get_dispid(&This->node, name, grfdex, pid);
1768
1769 return DISP_E_UNKNOWNNAME;
1770 }
1771
1772 static HRESULT HTMLElement_invoke(DispatchEx *dispex, DISPID id, LCID lcid,
1773 WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei,
1774 IServiceProvider *caller)
1775 {
1776 HTMLElement *This = impl_from_DispatchEx(dispex);
1777
1778 if(This->node.vtbl->invoke)
1779 return This->node.vtbl->invoke(&This->node, id, lcid, flags,
1780 params, res, ei, caller);
1781
1782 ERR("(%p): element has no invoke method\n", This);
1783 return E_NOTIMPL;
1784 }
1785
1786 static HRESULT HTMLElement_populate_props(DispatchEx *dispex)
1787 {
1788 HTMLElement *This = impl_from_DispatchEx(dispex);
1789 nsIDOMMozNamedAttrMap *attrs;
1790 nsIDOMAttr *attr;
1791 nsAString nsstr;
1792 const PRUnichar *str;
1793 BSTR name;
1794 VARIANT value;
1795 unsigned i;
1796 UINT32 len;
1797 DISPID id;
1798 nsresult nsres;
1799 HRESULT hres;
1800
1801 if(!This->nselem)
1802 return S_FALSE;
1803
1804 nsres = nsIDOMHTMLElement_GetAttributes(This->nselem, &attrs);
1805 if(NS_FAILED(nsres))
1806 return E_FAIL;
1807
1808 nsres = nsIDOMMozNamedAttrMap_GetLength(attrs, &len);
1809 if(NS_FAILED(nsres)) {
1810 nsIDOMMozNamedAttrMap_Release(attrs);
1811 return E_FAIL;
1812 }
1813
1814 nsAString_Init(&nsstr, NULL);
1815 for(i=0; i<len; i++) {
1816 nsres = nsIDOMMozNamedAttrMap_Item(attrs, i, &attr);
1817 if(NS_FAILED(nsres))
1818 continue;
1819
1820 nsres = nsIDOMAttr_GetNodeName(attr, &nsstr);
1821 if(NS_FAILED(nsres)) {
1822 nsIDOMAttr_Release(attr);
1823 continue;
1824 }
1825
1826 nsAString_GetData(&nsstr, &str);
1827 name = SysAllocString(str);
1828 if(!name) {
1829 nsIDOMAttr_Release(attr);
1830 continue;
1831 }
1832
1833 hres = IDispatchEx_GetDispID(&dispex->IDispatchEx_iface, name, fdexNameCaseInsensitive, &id);
1834 if(hres != DISP_E_UNKNOWNNAME) {
1835 nsIDOMAttr_Release(attr);
1836 SysFreeString(name);
1837 continue;
1838 }
1839
1840 nsres = nsIDOMAttr_GetNodeValue(attr, &nsstr);
1841 nsIDOMAttr_Release(attr);
1842 if(NS_FAILED(nsres)) {
1843 SysFreeString(name);
1844 continue;
1845 }
1846
1847 nsAString_GetData(&nsstr, &str);
1848 V_VT(&value) = VT_BSTR;
1849 if(*str) {
1850 V_BSTR(&value) = SysAllocString(str);
1851 if(!V_BSTR(&value)) {
1852 SysFreeString(name);
1853 continue;
1854 }
1855 } else
1856 V_BSTR(&value) = NULL;
1857
1858 IHTMLElement_setAttribute(&This->IHTMLElement_iface, name, value, 0);
1859 SysFreeString(name);
1860 VariantClear(&value);
1861 }
1862 nsAString_Finish(&nsstr);
1863
1864 nsIDOMMozNamedAttrMap_Release(attrs);
1865 return S_OK;
1866 }
1867
1868 static const tid_t HTMLElement_iface_tids[] = {
1869 HTMLELEMENT_TIDS,
1870 0
1871 };
1872
1873 static dispex_static_data_vtbl_t HTMLElement_dispex_vtbl = {
1874 NULL,
1875 HTMLElement_get_dispid,
1876 HTMLElement_invoke,
1877 HTMLElement_populate_props
1878 };
1879
1880 static dispex_static_data_t HTMLElement_dispex = {
1881 &HTMLElement_dispex_vtbl,
1882 DispHTMLUnknownElement_tid,
1883 NULL,
1884 HTMLElement_iface_tids
1885 };
1886
1887 void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, dispex_static_data_t *dispex_data)
1888 {
1889 This->IHTMLElement_iface.lpVtbl = &HTMLElementVtbl;
1890
1891 HTMLElement2_Init(This);
1892 HTMLElement3_Init(This);
1893
1894 if(dispex_data && !dispex_data->vtbl)
1895 dispex_data->vtbl = &HTMLElement_dispex_vtbl;
1896 init_dispex(&This->node.dispex, (IUnknown*)&This->IHTMLElement_iface,
1897 dispex_data ? dispex_data : &HTMLElement_dispex);
1898
1899 if(nselem) {
1900 HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem);
1901
1902 /* No AddRef, share reference with HTMLDOMNode */
1903 assert((nsIDOMNode*)nselem == This->node.nsnode);
1904 This->nselem = nselem;
1905 }
1906
1907 This->node.cp_container = &This->cp_container;
1908 ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)&This->IHTMLElement_iface, This->node.vtbl->cpc_entries);
1909 }
1910
1911 HRESULT HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_generic, HTMLElement **ret)
1912 {
1913 nsIDOMHTMLElement *nselem;
1914 nsAString class_name_str;
1915 const PRUnichar *class_name;
1916 const tag_desc_t *tag;
1917 HTMLElement *elem;
1918 nsresult nsres;
1919 HRESULT hres;
1920
1921 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1922 if(NS_FAILED(nsres))
1923 return E_FAIL;
1924
1925 nsAString_Init(&class_name_str, NULL);
1926 nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1927
1928 nsAString_GetData(&class_name_str, &class_name);
1929
1930 tag = get_tag_desc(class_name);
1931 if(tag) {
1932 hres = tag->constructor(doc, nselem, &elem);
1933 }else if(use_generic) {
1934 hres = HTMLGenericElement_Create(doc, nselem, &elem);
1935 }else {
1936 elem = heap_alloc_zero(sizeof(HTMLElement));
1937 if(elem) {
1938 elem->node.vtbl = &HTMLElementImplVtbl;
1939 HTMLElement_Init(elem, doc, nselem, &HTMLElement_dispex);
1940 hres = S_OK;
1941 }else {
1942 hres = E_OUTOFMEMORY;
1943 }
1944 }
1945
1946 TRACE("%s ret %p\n", debugstr_w(class_name), elem);
1947
1948 nsIDOMHTMLElement_Release(nselem);
1949 nsAString_Finish(&class_name_str);
1950 if(FAILED(hres))
1951 return hres;
1952
1953 *ret = elem;
1954 return S_OK;
1955 }
1956
1957 HRESULT get_elem(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **ret)
1958 {
1959 HTMLDOMNode *node;
1960 HRESULT hres;
1961
1962 hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node);
1963 if(FAILED(hres))
1964 return hres;
1965
1966 *ret = impl_from_HTMLDOMNode(node);
1967 return S_OK;
1968 }
1969
1970 /* interface IHTMLFiltersCollection */
1971 static HRESULT WINAPI HTMLFiltersCollection_QueryInterface(IHTMLFiltersCollection *iface, REFIID riid, void **ppv)
1972 {
1973 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
1974
1975 TRACE("%p %s %p\n", This, debugstr_mshtml_guid(riid), ppv );
1976
1977 if(IsEqualGUID(&IID_IUnknown, riid)) {
1978 *ppv = &This->IHTMLFiltersCollection_iface;
1979 }else if(IsEqualGUID(&IID_IHTMLFiltersCollection, riid)) {
1980 TRACE("(%p)->(IID_IHTMLFiltersCollection %p)\n", This, ppv);
1981 *ppv = &This->IHTMLFiltersCollection_iface;
1982 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
1983 return *ppv ? S_OK : E_NOINTERFACE;
1984 }else {
1985 *ppv = NULL;
1986 FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1987 return E_NOINTERFACE;
1988 }
1989
1990 IUnknown_AddRef((IUnknown*)*ppv);
1991 return S_OK;
1992 }
1993
1994 static ULONG WINAPI HTMLFiltersCollection_AddRef(IHTMLFiltersCollection *iface)
1995 {
1996 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
1997 LONG ref = InterlockedIncrement(&This->ref);
1998
1999 TRACE("(%p) ref=%d\n", This, ref);
2000
2001 return ref;
2002 }
2003
2004 static ULONG WINAPI HTMLFiltersCollection_Release(IHTMLFiltersCollection *iface)
2005 {
2006 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2007 LONG ref = InterlockedDecrement(&This->ref);
2008
2009 TRACE("(%p) ref=%d\n", This, ref);
2010
2011 if(!ref)
2012 {
2013 heap_free(This);
2014 }
2015
2016 return ref;
2017 }
2018
2019 static HRESULT WINAPI HTMLFiltersCollection_GetTypeInfoCount(IHTMLFiltersCollection *iface, UINT *pctinfo)
2020 {
2021 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2022 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2023 }
2024
2025 static HRESULT WINAPI HTMLFiltersCollection_GetTypeInfo(IHTMLFiltersCollection *iface,
2026 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
2027 {
2028 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2029 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2030 }
2031
2032 static HRESULT WINAPI HTMLFiltersCollection_GetIDsOfNames(IHTMLFiltersCollection *iface,
2033 REFIID riid, LPOLESTR *rgszNames, UINT cNames,
2034 LCID lcid, DISPID *rgDispId)
2035 {
2036 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2037 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
2038 lcid, rgDispId);
2039 }
2040
2041 static HRESULT WINAPI HTMLFiltersCollection_Invoke(IHTMLFiltersCollection *iface, DISPID dispIdMember, REFIID riid,
2042 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2043 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2044 {
2045 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2046 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
2047 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2048 }
2049
2050 static HRESULT WINAPI HTMLFiltersCollection_get_length(IHTMLFiltersCollection *iface, LONG *p)
2051 {
2052 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2053
2054 if(!p)
2055 return E_POINTER;
2056
2057 FIXME("(%p)->(%p) Always returning 0\n", This, p);
2058 *p = 0;
2059
2060 return S_OK;
2061 }
2062
2063 static HRESULT WINAPI HTMLFiltersCollection_get__newEnum(IHTMLFiltersCollection *iface, IUnknown **p)
2064 {
2065 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2066 FIXME("(%p)->(%p)\n", This, p);
2067 return E_NOTIMPL;
2068 }
2069
2070 static HRESULT WINAPI HTMLFiltersCollection_item(IHTMLFiltersCollection *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
2071 {
2072 HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface);
2073 FIXME("(%p)->(%p, %p)\n", This, pvarIndex, pvarResult);
2074 return E_NOTIMPL;
2075 }
2076
2077 static const IHTMLFiltersCollectionVtbl HTMLFiltersCollectionVtbl = {
2078 HTMLFiltersCollection_QueryInterface,
2079 HTMLFiltersCollection_AddRef,
2080 HTMLFiltersCollection_Release,
2081 HTMLFiltersCollection_GetTypeInfoCount,
2082 HTMLFiltersCollection_GetTypeInfo,
2083 HTMLFiltersCollection_GetIDsOfNames,
2084 HTMLFiltersCollection_Invoke,
2085 HTMLFiltersCollection_get_length,
2086 HTMLFiltersCollection_get__newEnum,
2087 HTMLFiltersCollection_item
2088 };
2089
2090 static HRESULT HTMLFiltersCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
2091 {
2092 WCHAR *ptr;
2093 int idx = 0;
2094
2095 for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
2096 idx = idx*10 + (*ptr-'0');
2097 if(*ptr)
2098 return DISP_E_UNKNOWNNAME;
2099
2100 *dispid = MSHTML_DISPID_CUSTOM_MIN + idx;
2101 TRACE("ret %x\n", *dispid);
2102 return S_OK;
2103 }
2104
2105 static HRESULT HTMLFiltersCollection_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
2106 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
2107 {
2108 TRACE("(%p)->(%x %x %x %p %p %p)\n", dispex, id, lcid, flags, params, res, ei);
2109
2110 V_VT(res) = VT_DISPATCH;
2111 V_DISPATCH(res) = NULL;
2112
2113 FIXME("always returning NULL\n");
2114
2115 return S_OK;
2116 }
2117
2118 static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = {
2119 NULL,
2120 HTMLFiltersCollection_get_dispid,
2121 HTMLFiltersCollection_invoke,
2122 NULL
2123 };
2124
2125 static const tid_t HTMLFiltersCollection_iface_tids[] = {
2126 IHTMLFiltersCollection_tid,
2127 0
2128 };
2129 static dispex_static_data_t HTMLFiltersCollection_dispex = {
2130 &HTMLFiltersCollection_dispex_vtbl,
2131 IHTMLFiltersCollection_tid,
2132 NULL,
2133 HTMLFiltersCollection_iface_tids
2134 };
2135
2136 static IHTMLFiltersCollection *HTMLFiltersCollection_Create(void)
2137 {
2138 HTMLFiltersCollection *ret = heap_alloc(sizeof(HTMLFiltersCollection));
2139
2140 ret->IHTMLFiltersCollection_iface.lpVtbl = &HTMLFiltersCollectionVtbl;
2141 ret->ref = 1;
2142
2143 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLFiltersCollection_iface,
2144 &HTMLFiltersCollection_dispex);
2145
2146 return &ret->IHTMLFiltersCollection_iface;
2147 }
2148
2149 /* interface IHTMLAttributeCollection */
2150 static inline HTMLAttributeCollection *impl_from_IHTMLAttributeCollection(IHTMLAttributeCollection *iface)
2151 {
2152 return CONTAINING_RECORD(iface, HTMLAttributeCollection, IHTMLAttributeCollection_iface);
2153 }
2154
2155 static HRESULT WINAPI HTMLAttributeCollection_QueryInterface(IHTMLAttributeCollection *iface, REFIID riid, void **ppv)
2156 {
2157 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2158
2159 if(IsEqualGUID(&IID_IUnknown, riid)) {
2160 *ppv = &This->IHTMLAttributeCollection_iface;
2161 }else if(IsEqualGUID(&IID_IHTMLAttributeCollection, riid)) {
2162 *ppv = &This->IHTMLAttributeCollection_iface;
2163 }else if(IsEqualGUID(&IID_IHTMLAttributeCollection2, riid)) {
2164 *ppv = &This->IHTMLAttributeCollection2_iface;
2165 }else if(IsEqualGUID(&IID_IHTMLAttributeCollection3, riid)) {
2166 *ppv = &This->IHTMLAttributeCollection3_iface;
2167 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
2168 return *ppv ? S_OK : E_NOINTERFACE;
2169 }else {
2170 *ppv = NULL;
2171 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
2172 return E_NOINTERFACE;
2173 }
2174
2175 IUnknown_AddRef((IUnknown*)*ppv);
2176 return S_OK;
2177 }
2178
2179 static ULONG WINAPI HTMLAttributeCollection_AddRef(IHTMLAttributeCollection *iface)
2180 {
2181 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2182 LONG ref = InterlockedIncrement(&This->ref);
2183
2184 TRACE("(%p) ref=%d\n", This, ref);
2185
2186 return ref;
2187 }
2188
2189 static ULONG WINAPI HTMLAttributeCollection_Release(IHTMLAttributeCollection *iface)
2190 {
2191 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2192 LONG ref = InterlockedDecrement(&This->ref);
2193
2194 TRACE("(%p) ref=%d\n", This, ref);
2195
2196 if(!ref) {
2197 while(!list_empty(&This->attrs)) {
2198 HTMLDOMAttribute *attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry);
2199
2200 list_remove(&attr->entry);
2201 attr->elem = NULL;
2202 IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface);
2203 }
2204
2205 heap_free(This);
2206 }
2207
2208 return ref;
2209 }
2210
2211 static HRESULT WINAPI HTMLAttributeCollection_GetTypeInfoCount(IHTMLAttributeCollection *iface, UINT *pctinfo)
2212 {
2213 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2214 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2215 }
2216
2217 static HRESULT WINAPI HTMLAttributeCollection_GetTypeInfo(IHTMLAttributeCollection *iface, UINT iTInfo,
2218 LCID lcid, ITypeInfo **ppTInfo)
2219 {
2220 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2221 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2222 }
2223
2224 static HRESULT WINAPI HTMLAttributeCollection_GetIDsOfNames(IHTMLAttributeCollection *iface, REFIID riid,
2225 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2226 {
2227 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2228 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
2229 lcid, rgDispId);
2230 }
2231
2232 static HRESULT WINAPI HTMLAttributeCollection_Invoke(IHTMLAttributeCollection *iface, DISPID dispIdMember,
2233 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
2234 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2235 {
2236 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2237 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
2238 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2239 }
2240
2241 static HRESULT get_attr_dispid_by_idx(HTMLAttributeCollection *This, LONG *idx, DISPID *dispid)
2242 {
2243 IDispatchEx *dispex = &This->elem->node.dispex.IDispatchEx_iface;
2244 DISPID id = DISPID_STARTENUM;
2245 LONG len = -1;
2246 HRESULT hres;
2247
2248 FIXME("filter non-enumerable attributes out\n");
2249
2250 while(1) {
2251 hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, id, &id);
2252 if(FAILED(hres))
2253 return hres;
2254 else if(hres == S_FALSE)
2255 break;
2256
2257 len++;
2258 if(len == *idx)
2259 break;
2260 }
2261
2262 if(dispid) {
2263 *dispid = id;
2264 return *idx==len ? S_OK : DISP_E_UNKNOWNNAME;
2265 }
2266
2267 *idx = len+1;
2268 return S_OK;
2269 }
2270
2271 static inline HRESULT get_attr_dispid_by_name(HTMLAttributeCollection *This, BSTR name, DISPID *id)
2272 {
2273 HRESULT hres;
2274
2275 if(name[0]>='0' && name[0]<='9') {
2276 WCHAR *end_ptr;
2277 LONG idx;
2278
2279 idx = strtoulW(name, &end_ptr, 10);
2280 if(!*end_ptr) {
2281 hres = get_attr_dispid_by_idx(This, &idx, id);
2282 if(SUCCEEDED(hres))
2283 return hres;
2284 }
2285 }
2286
2287 if(!This->elem) {
2288 WARN("NULL elem\n");
2289 return E_UNEXPECTED;
2290 }
2291
2292 hres = IDispatchEx_GetDispID(&This->elem->node.dispex.IDispatchEx_iface,
2293 name, fdexNameCaseInsensitive, id);
2294 return hres;
2295 }
2296
2297 static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG *list_pos, HTMLDOMAttribute **attr)
2298 {
2299 HTMLDOMAttribute *iter;
2300 LONG pos = 0;
2301 HRESULT hres;
2302
2303 *attr = NULL;
2304 LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
2305 if(iter->dispid == id) {
2306 *attr = iter;
2307 break;
2308 }
2309 pos++;
2310 }
2311
2312 if(!*attr) {
2313 if(!This->elem) {
2314 WARN("NULL elem\n");
2315 return E_UNEXPECTED;
2316 }
2317
2318 hres = HTMLDOMAttribute_Create(NULL, This->elem, id, attr);
2319 if(FAILED(hres))
2320 return hres;
2321 }
2322
2323 IHTMLDOMAttribute_AddRef(&(*attr)->IHTMLDOMAttribute_iface);
2324 if(list_pos)
2325 *list_pos = pos;
2326 return S_OK;
2327 }
2328
2329 static HRESULT WINAPI HTMLAttributeCollection_get_length(IHTMLAttributeCollection *iface, LONG *p)
2330 {
2331 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2332 HRESULT hres;
2333
2334 TRACE("(%p)->(%p)\n", This, p);
2335
2336 *p = -1;
2337 hres = get_attr_dispid_by_idx(This, p, NULL);
2338 return hres;
2339 }
2340
2341 static HRESULT WINAPI HTMLAttributeCollection__newEnum(IHTMLAttributeCollection *iface, IUnknown **p)
2342 {
2343 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2344 FIXME("(%p)->(%p)\n", This, p);
2345 return E_NOTIMPL;
2346 }
2347
2348 static HRESULT WINAPI HTMLAttributeCollection_item(IHTMLAttributeCollection *iface, VARIANT *name, IDispatch **ppItem)
2349 {
2350 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
2351 HTMLDOMAttribute *attr;
2352 DISPID id;
2353 HRESULT hres;
2354
2355 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(name), ppItem);
2356
2357 switch(V_VT(name)) {
2358 case VT_I4:
2359 hres = get_attr_dispid_by_idx(This, &V_I4(name), &id);
2360 break;
2361 case VT_BSTR:
2362 hres = get_attr_dispid_by_name(This, V_BSTR(name), &id);
2363 break;
2364 default:
2365 FIXME("unsupported name %s\n", debugstr_variant(name));
2366 hres = E_NOTIMPL;
2367 }
2368 if(hres == DISP_E_UNKNOWNNAME)
2369 return E_INVALIDARG;
2370 if(FAILED(hres))
2371 return hres;
2372
2373 hres = get_domattr(This, id, NULL, &attr);
2374 if(FAILED(hres))
2375 return hres;
2376
2377 *ppItem = (IDispatch*)&attr->IHTMLDOMAttribute_iface;
2378 return S_OK;
2379 }
2380
2381 static const IHTMLAttributeCollectionVtbl HTMLAttributeCollectionVtbl = {
2382 HTMLAttributeCollection_QueryInterface,
2383 HTMLAttributeCollection_AddRef,
2384 HTMLAttributeCollection_Release,
2385 HTMLAttributeCollection_GetTypeInfoCount,
2386 HTMLAttributeCollection_GetTypeInfo,
2387 HTMLAttributeCollection_GetIDsOfNames,
2388 HTMLAttributeCollection_Invoke,
2389 HTMLAttributeCollection_get_length,
2390 HTMLAttributeCollection__newEnum,
2391 HTMLAttributeCollection_item
2392 };
2393
2394 static inline HTMLAttributeCollection *impl_from_IHTMLAttributeCollection2(IHTMLAttributeCollection2 *iface)
2395 {
2396 return CONTAINING_RECORD(iface, HTMLAttributeCollection, IHTMLAttributeCollection2_iface);
2397 }
2398
2399 static HRESULT WINAPI HTMLAttributeCollection2_QueryInterface(IHTMLAttributeCollection2 *iface, REFIID riid, void **ppv)
2400 {
2401 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2402 return IHTMLAttributeCollection_QueryInterface(&This->IHTMLAttributeCollection_iface, riid, ppv);
2403 }
2404
2405 static ULONG WINAPI HTMLAttributeCollection2_AddRef(IHTMLAttributeCollection2 *iface)
2406 {
2407 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2408 return IHTMLAttributeCollection_AddRef(&This->IHTMLAttributeCollection_iface);
2409 }
2410
2411 static ULONG WINAPI HTMLAttributeCollection2_Release(IHTMLAttributeCollection2 *iface)
2412 {
2413 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2414 return IHTMLAttributeCollection_Release(&This->IHTMLAttributeCollection_iface);
2415 }
2416
2417 static HRESULT WINAPI HTMLAttributeCollection2_GetTypeInfoCount(IHTMLAttributeCollection2 *iface, UINT *pctinfo)
2418 {
2419 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2420 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2421 }
2422
2423 static HRESULT WINAPI HTMLAttributeCollection2_GetTypeInfo(IHTMLAttributeCollection2 *iface, UINT iTInfo,
2424 LCID lcid, ITypeInfo **ppTInfo)
2425 {
2426 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2427 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2428 }
2429
2430 static HRESULT WINAPI HTMLAttributeCollection2_GetIDsOfNames(IHTMLAttributeCollection2 *iface, REFIID riid,
2431 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2432 {
2433 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2434 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
2435 lcid, rgDispId);
2436 }
2437
2438 static HRESULT WINAPI HTMLAttributeCollection2_Invoke(IHTMLAttributeCollection2 *iface, DISPID dispIdMember,
2439 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
2440 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2441 {
2442 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2443 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
2444 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2445 }
2446
2447 static HRESULT WINAPI HTMLAttributeCollection2_getNamedItem(IHTMLAttributeCollection2 *iface, BSTR bstrName,
2448 IHTMLDOMAttribute **newretNode)
2449 {
2450 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2451 HTMLDOMAttribute *attr;
2452 DISPID id;
2453 HRESULT hres;
2454
2455 TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrName), newretNode);
2456
2457 hres = get_attr_dispid_by_name(This, bstrName, &id);
2458 if(hres == DISP_E_UNKNOWNNAME) {
2459 *newretNode = NULL;
2460 return S_OK;
2461 } else if(FAILED(hres)) {
2462 return hres;
2463 }
2464
2465 hres = get_domattr(This, id, NULL, &attr);
2466 if(FAILED(hres))
2467 return hres;
2468
2469 *newretNode = &attr->IHTMLDOMAttribute_iface;
2470 return S_OK;
2471 }
2472
2473 static HRESULT WINAPI HTMLAttributeCollection2_setNamedItem(IHTMLAttributeCollection2 *iface,
2474 IHTMLDOMAttribute *ppNode, IHTMLDOMAttribute **newretNode)
2475 {
2476 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2477 FIXME("(%p)->(%p %p)\n", This, ppNode, newretNode);
2478 return E_NOTIMPL;
2479 }
2480
2481 static HRESULT WINAPI HTMLAttributeCollection2_removeNamedItem(IHTMLAttributeCollection2 *iface,
2482 BSTR bstrName, IHTMLDOMAttribute **newretNode)
2483 {
2484 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection2(iface);
2485 FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrName), newretNode);
2486 return E_NOTIMPL;
2487 }
2488
2489 static const IHTMLAttributeCollection2Vtbl HTMLAttributeCollection2Vtbl = {
2490 HTMLAttributeCollection2_QueryInterface,
2491 HTMLAttributeCollection2_AddRef,
2492 HTMLAttributeCollection2_Release,
2493 HTMLAttributeCollection2_GetTypeInfoCount,
2494 HTMLAttributeCollection2_GetTypeInfo,
2495 HTMLAttributeCollection2_GetIDsOfNames,
2496 HTMLAttributeCollection2_Invoke,
2497 HTMLAttributeCollection2_getNamedItem,
2498 HTMLAttributeCollection2_setNamedItem,
2499 HTMLAttributeCollection2_removeNamedItem
2500 };
2501
2502 static inline HTMLAttributeCollection *impl_from_IHTMLAttributeCollection3(IHTMLAttributeCollection3 *iface)
2503 {
2504 return CONTAINING_RECORD(iface, HTMLAttributeCollection, IHTMLAttributeCollection3_iface);
2505 }
2506
2507 static HRESULT WINAPI HTMLAttributeCollection3_QueryInterface(IHTMLAttributeCollection3 *iface, REFIID riid, void **ppv)
2508 {
2509 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2510 return IHTMLAttributeCollection_QueryInterface(&This->IHTMLAttributeCollection_iface, riid, ppv);
2511 }
2512
2513 static ULONG WINAPI HTMLAttributeCollection3_AddRef(IHTMLAttributeCollection3 *iface)
2514 {
2515 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2516 return IHTMLAttributeCollection_AddRef(&This->IHTMLAttributeCollection_iface);
2517 }
2518
2519 static ULONG WINAPI HTMLAttributeCollection3_Release(IHTMLAttributeCollection3 *iface)
2520 {
2521 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2522 return IHTMLAttributeCollection_Release(&This->IHTMLAttributeCollection_iface);
2523 }
2524
2525 static HRESULT WINAPI HTMLAttributeCollection3_GetTypeInfoCount(IHTMLAttributeCollection3 *iface, UINT *pctinfo)
2526 {
2527 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2528 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2529 }
2530
2531 static HRESULT WINAPI HTMLAttributeCollection3_GetTypeInfo(IHTMLAttributeCollection3 *iface, UINT iTInfo,
2532 LCID lcid, ITypeInfo **ppTInfo)
2533 {
2534 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2535 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2536 }
2537
2538 static HRESULT WINAPI HTMLAttributeCollection3_GetIDsOfNames(IHTMLAttributeCollection3 *iface, REFIID riid,
2539 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2540 {
2541 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2542 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
2543 lcid, rgDispId);
2544 }
2545
2546 static HRESULT WINAPI HTMLAttributeCollection3_Invoke(IHTMLAttributeCollection3 *iface, DISPID dispIdMember,
2547 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
2548 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2549 {
2550 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2551 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
2552 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2553 }
2554
2555 static HRESULT WINAPI HTMLAttributeCollection3_getNamedItem(IHTMLAttributeCollection3 *iface, BSTR bstrName,
2556 IHTMLDOMAttribute **ppNodeOut)
2557 {
2558 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2559 return IHTMLAttributeCollection2_getNamedItem(&This->IHTMLAttributeCollection2_iface, bstrName, ppNodeOut);
2560 }
2561
2562 static HRESULT WINAPI HTMLAttributeCollection3_setNamedItem(IHTMLAttributeCollection3 *iface,
2563 IHTMLDOMAttribute *pNodeIn, IHTMLDOMAttribute **ppNodeOut)
2564 {
2565 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2566 FIXME("(%p)->(%p %p)\n", This, pNodeIn, ppNodeOut);
2567 return E_NOTIMPL;
2568 }
2569
2570 static HRESULT WINAPI HTMLAttributeCollection3_removeNamedItem(IHTMLAttributeCollection3 *iface,
2571 BSTR bstrName, IHTMLDOMAttribute **ppNodeOut)
2572 {
2573 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2574 FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrName), ppNodeOut);
2575 return E_NOTIMPL;
2576 }
2577
2578 static HRESULT WINAPI HTMLAttributeCollection3_item(IHTMLAttributeCollection3 *iface, LONG index, IHTMLDOMAttribute **ppNodeOut)
2579 {
2580 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2581 HTMLDOMAttribute *attr;
2582 DISPID id;
2583 HRESULT hres;
2584
2585 TRACE("(%p)->(%d %p)\n", This, index, ppNodeOut);
2586
2587 hres = get_attr_dispid_by_idx(This, &index, &id);
2588 if(hres == DISP_E_UNKNOWNNAME)
2589 return E_INVALIDARG;
2590 if(FAILED(hres))
2591 return hres;
2592
2593 hres = get_domattr(This, id, NULL, &attr);
2594 if(FAILED(hres))
2595 return hres;
2596
2597 *ppNodeOut = &attr->IHTMLDOMAttribute_iface;
2598 return S_OK;
2599 }
2600
2601 static HRESULT WINAPI HTMLAttributeCollection3_get_length(IHTMLAttributeCollection3 *iface, LONG *p)
2602 {
2603 HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection3(iface);
2604 return IHTMLAttributeCollection_get_length(&This->IHTMLAttributeCollection_iface, p);
2605 }
2606
2607 static const IHTMLAttributeCollection3Vtbl HTMLAttributeCollection3Vtbl = {
2608 HTMLAttributeCollection3_QueryInterface,
2609 HTMLAttributeCollection3_AddRef,
2610 HTMLAttributeCollection3_Release,
2611 HTMLAttributeCollection3_GetTypeInfoCount,
2612 HTMLAttributeCollection3_GetTypeInfo,
2613 HTMLAttributeCollection3_GetIDsOfNames,
2614 HTMLAttributeCollection3_Invoke,
2615 HTMLAttributeCollection3_getNamedItem,
2616 HTMLAttributeCollection3_setNamedItem,
2617 HTMLAttributeCollection3_removeNamedItem,
2618 HTMLAttributeCollection3_item,
2619 HTMLAttributeCollection3_get_length
2620 };
2621
2622 static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(DispatchEx *iface)
2623 {
2624 return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex);
2625 }
2626
2627 static HRESULT HTMLAttributeCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
2628 {
2629 HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex);
2630 HTMLDOMAttribute *attr;
2631 LONG pos;
2632 HRESULT hres;
2633
2634 TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(name), flags, dispid);
2635
2636 hres = get_attr_dispid_by_name(This, name, dispid);
2637 if(FAILED(hres))
2638 return hres;
2639
2640 hres = get_domattr(This, *dispid, &pos, &attr);
2641 if(FAILED(hres))
2642 return hres;
2643 IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface);
2644
2645 *dispid = MSHTML_DISPID_CUSTOM_MIN+pos;
2646 return S_OK;
2647 }
2648
2649 static HRESULT HTMLAttributeCollection_invoke(DispatchEx *dispex, DISPID id, LCID lcid,
2650 WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
2651 {
2652 HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex);
2653
2654 TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller);
2655
2656 switch(flags) {
2657 case DISPATCH_PROPERTYGET: {
2658 HTMLDOMAttribute *iter;
2659 DWORD pos;
2660
2661 pos = id-MSHTML_DISPID_CUSTOM_MIN;
2662
2663 LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
2664 if(!pos) {
2665 IHTMLDOMAttribute_AddRef(&iter->IHTMLDOMAttribute_iface);
2666 V_VT(res) = VT_DISPATCH;
2667 V_DISPATCH(res) = (IDispatch*)&iter->IHTMLDOMAttribute_iface;
2668 return S_OK;
2669 }
2670 pos--;
2671 }
2672
2673 WARN("invalid arg\n");
2674 return E_INVALIDARG;
2675 }
2676
2677 default:
2678 FIXME("unimplemented flags %x\n", flags);
2679 return E_NOTIMPL;
2680 }
2681 }
2682
2683 static const dispex_static_data_vtbl_t HTMLAttributeCollection_dispex_vtbl = {
2684 NULL,
2685 HTMLAttributeCollection_get_dispid,
2686 HTMLAttributeCollection_invoke,
2687 NULL
2688 };
2689
2690 static const tid_t HTMLAttributeCollection_iface_tids[] = {
2691 IHTMLAttributeCollection_tid,
2692 IHTMLAttributeCollection2_tid,
2693 IHTMLAttributeCollection3_tid,
2694 0
2695 };
2696
2697 static dispex_static_data_t HTMLAttributeCollection_dispex = {
2698 &HTMLAttributeCollection_dispex_vtbl,
2699 DispHTMLAttributeCollection_tid,
2700 NULL,
2701 HTMLAttributeCollection_iface_tids
2702 };
2703
2704 HRESULT HTMLElement_get_attr_col(HTMLDOMNode *iface, HTMLAttributeCollection **ac)
2705 {
2706 HTMLElement *This = impl_from_HTMLDOMNode(iface);
2707
2708 if(This->attrs) {
2709 IHTMLAttributeCollection_AddRef(&This->attrs->IHTMLAttributeCollection_iface);
2710 *ac = This->attrs;
2711 return S_OK;
2712 }
2713
2714 This->attrs = heap_alloc_zero(sizeof(HTMLAttributeCollection));
2715 if(!This->attrs)
2716 return E_OUTOFMEMORY;
2717
2718 This->attrs->IHTMLAttributeCollection_iface.lpVtbl = &HTMLAttributeCollectionVtbl;
2719 This->attrs->IHTMLAttributeCollection2_iface.lpVtbl = &HTMLAttributeCollection2Vtbl;
2720 This->attrs->IHTMLAttributeCollection3_iface.lpVtbl = &HTMLAttributeCollection3Vtbl;
2721 This->attrs->ref = 2;
2722
2723 This->attrs->elem = This;
2724 list_init(&This->attrs->attrs);
2725 init_dispex(&This->attrs->dispex, (IUnknown*)&This->attrs->IHTMLAttributeCollection_iface,
2726 &HTMLAttributeCollection_dispex);
2727
2728 *ac = This->attrs;
2729 return S_OK;
2730 }