Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhtmlnode.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006 Jacek Caban for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include <stdarg.h> 00020 00021 #define COBJMACROS 00022 00023 #include "windef.h" 00024 #include "winbase.h" 00025 #include "winuser.h" 00026 #include "ole2.h" 00027 00028 #include "wine/debug.h" 00029 00030 #include "mshtml_private.h" 00031 #include "htmlevent.h" 00032 00033 WINE_DEFAULT_DEBUG_CHANNEL(mshtml); 00034 00035 static HTMLDOMNode *get_node_obj(HTMLDocumentNode*,IUnknown*); 00036 00037 typedef struct { 00038 DispatchEx dispex; 00039 const IHTMLDOMChildrenCollectionVtbl *lpIHTMLDOMChildrenCollectionVtbl; 00040 00041 LONG ref; 00042 00043 /* FIXME: implement weak reference */ 00044 HTMLDocumentNode *doc; 00045 00046 nsIDOMNodeList *nslist; 00047 } HTMLDOMChildrenCollection; 00048 00049 #define HTMLCHILDCOL(x) ((IHTMLDOMChildrenCollection*) &(x)->lpIHTMLDOMChildrenCollectionVtbl) 00050 00051 #define HTMLCHILDCOL_THIS(iface) DEFINE_THIS(HTMLDOMChildrenCollection, IHTMLDOMChildrenCollection, iface) 00052 00053 static HRESULT WINAPI HTMLDOMChildrenCollection_QueryInterface(IHTMLDOMChildrenCollection *iface, REFIID riid, void **ppv) 00054 { 00055 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00056 00057 *ppv = NULL; 00058 00059 if(IsEqualGUID(&IID_IUnknown, riid)) { 00060 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 00061 *ppv = HTMLCHILDCOL(This); 00062 }else if(IsEqualGUID(&IID_IHTMLDOMChildrenCollection, riid)) { 00063 TRACE("(%p)->(IID_IHTMLDOMChildrenCollection %p)\n", This, ppv); 00064 *ppv = HTMLCHILDCOL(This); 00065 }else if(dispex_query_interface(&This->dispex, riid, ppv)) { 00066 return *ppv ? S_OK : E_NOINTERFACE; 00067 } 00068 00069 if(*ppv) { 00070 IUnknown_AddRef((IUnknown*)*ppv); 00071 return S_OK; 00072 } 00073 00074 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 00075 return E_NOINTERFACE; 00076 } 00077 00078 static ULONG WINAPI HTMLDOMChildrenCollection_AddRef(IHTMLDOMChildrenCollection *iface) 00079 { 00080 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00081 LONG ref = InterlockedIncrement(&This->ref); 00082 00083 TRACE("(%p) ref=%d\n", This, ref); 00084 00085 return ref; 00086 } 00087 00088 static ULONG WINAPI HTMLDOMChildrenCollection_Release(IHTMLDOMChildrenCollection *iface) 00089 { 00090 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00091 LONG ref = InterlockedDecrement(&This->ref); 00092 00093 TRACE("(%p) ref=%d\n", This, ref); 00094 00095 if(!ref) { 00096 nsIDOMNodeList_Release(This->nslist); 00097 heap_free(This); 00098 } 00099 00100 return ref; 00101 } 00102 00103 static HRESULT WINAPI HTMLDOMChildrenCollection_GetTypeInfoCount(IHTMLDOMChildrenCollection *iface, UINT *pctinfo) 00104 { 00105 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00106 return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); 00107 } 00108 00109 static HRESULT WINAPI HTMLDOMChildrenCollection_GetTypeInfo(IHTMLDOMChildrenCollection *iface, UINT iTInfo, 00110 LCID lcid, ITypeInfo **ppTInfo) 00111 { 00112 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00113 return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); 00114 } 00115 00116 static HRESULT WINAPI HTMLDOMChildrenCollection_GetIDsOfNames(IHTMLDOMChildrenCollection *iface, REFIID riid, 00117 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 00118 { 00119 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00120 return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); 00121 } 00122 00123 static HRESULT WINAPI HTMLDOMChildrenCollection_Invoke(IHTMLDOMChildrenCollection *iface, DISPID dispIdMember, 00124 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 00125 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 00126 { 00127 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00128 return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, 00129 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 00130 } 00131 00132 static HRESULT WINAPI HTMLDOMChildrenCollection_get_length(IHTMLDOMChildrenCollection *iface, LONG *p) 00133 { 00134 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00135 PRUint32 length=0; 00136 00137 TRACE("(%p)->(%p)\n", This, p); 00138 00139 nsIDOMNodeList_GetLength(This->nslist, &length); 00140 *p = length; 00141 return S_OK; 00142 } 00143 00144 static HRESULT WINAPI HTMLDOMChildrenCollection__newEnum(IHTMLDOMChildrenCollection *iface, IUnknown **p) 00145 { 00146 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00147 FIXME("(%p)->(%p)\n", This, p); 00148 return E_NOTIMPL; 00149 } 00150 00151 static HRESULT WINAPI HTMLDOMChildrenCollection_item(IHTMLDOMChildrenCollection *iface, LONG index, IDispatch **ppItem) 00152 { 00153 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00154 nsIDOMNode *nsnode = NULL; 00155 PRUint32 length=0; 00156 nsresult nsres; 00157 00158 TRACE("(%p)->(%d %p)\n", This, index, ppItem); 00159 00160 if (ppItem) 00161 *ppItem = NULL; 00162 else 00163 return E_POINTER; 00164 00165 nsIDOMNodeList_GetLength(This->nslist, &length); 00166 if(index < 0 || index >= length) 00167 return E_INVALIDARG; 00168 00169 nsres = nsIDOMNodeList_Item(This->nslist, index, &nsnode); 00170 if(NS_FAILED(nsres) || !nsnode) { 00171 ERR("Item failed: %08x\n", nsres); 00172 return E_FAIL; 00173 } 00174 00175 *ppItem = (IDispatch*)get_node(This->doc, nsnode, TRUE); 00176 IDispatch_AddRef(*ppItem); 00177 return S_OK; 00178 } 00179 00180 #define DISPID_CHILDCOL_0 MSHTML_DISPID_CUSTOM_MIN 00181 00182 static HRESULT HTMLDOMChildrenCollection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid) 00183 { 00184 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00185 WCHAR *ptr; 00186 DWORD idx=0; 00187 PRUint32 len = 0; 00188 00189 for(ptr = name; *ptr && isdigitW(*ptr); ptr++) 00190 idx = idx*10 + (*ptr-'0'); 00191 if(*ptr) 00192 return DISP_E_UNKNOWNNAME; 00193 00194 nsIDOMNodeList_GetLength(This->nslist, &len); 00195 if(idx >= len) 00196 return DISP_E_UNKNOWNNAME; 00197 00198 *dispid = DISPID_CHILDCOL_0 + idx; 00199 TRACE("ret %x\n", *dispid); 00200 return S_OK; 00201 } 00202 00203 static HRESULT HTMLDOMChildrenCollection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, 00204 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) 00205 { 00206 HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); 00207 00208 TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); 00209 00210 switch(flags) { 00211 case DISPATCH_PROPERTYGET: { 00212 IDispatch *disp = NULL; 00213 HRESULT hres; 00214 00215 hres = IHTMLDOMChildrenCollection_item(HTMLCHILDCOL(This), id - DISPID_CHILDCOL_0, &disp); 00216 if(0&&FAILED(hres)) 00217 return hres; 00218 00219 V_VT(res) = VT_DISPATCH; 00220 V_DISPATCH(res) = disp; 00221 break; 00222 } 00223 00224 default: 00225 FIXME("unimplemented flags %x\n", flags); 00226 return E_NOTIMPL; 00227 } 00228 00229 return S_OK; 00230 } 00231 00232 #undef HTMLCHILDCOL_THIS 00233 00234 static const IHTMLDOMChildrenCollectionVtbl HTMLDOMChildrenCollectionVtbl = { 00235 HTMLDOMChildrenCollection_QueryInterface, 00236 HTMLDOMChildrenCollection_AddRef, 00237 HTMLDOMChildrenCollection_Release, 00238 HTMLDOMChildrenCollection_GetTypeInfoCount, 00239 HTMLDOMChildrenCollection_GetTypeInfo, 00240 HTMLDOMChildrenCollection_GetIDsOfNames, 00241 HTMLDOMChildrenCollection_Invoke, 00242 HTMLDOMChildrenCollection_get_length, 00243 HTMLDOMChildrenCollection__newEnum, 00244 HTMLDOMChildrenCollection_item 00245 }; 00246 00247 static const tid_t HTMLDOMChildrenCollection_iface_tids[] = { 00248 IHTMLDOMChildrenCollection_tid, 00249 0 00250 }; 00251 00252 static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = { 00253 NULL, 00254 HTMLDOMChildrenCollection_get_dispid, 00255 HTMLDOMChildrenCollection_invoke 00256 }; 00257 00258 static dispex_static_data_t HTMLDOMChildrenCollection_dispex = { 00259 &HTMLDOMChildrenCollection_dispex_vtbl, 00260 DispDOMChildrenCollection_tid, 00261 NULL, 00262 HTMLDOMChildrenCollection_iface_tids 00263 }; 00264 00265 static IHTMLDOMChildrenCollection *create_child_collection(HTMLDocumentNode *doc, nsIDOMNodeList *nslist) 00266 { 00267 HTMLDOMChildrenCollection *ret; 00268 00269 ret = heap_alloc_zero(sizeof(*ret)); 00270 ret->lpIHTMLDOMChildrenCollectionVtbl = &HTMLDOMChildrenCollectionVtbl; 00271 ret->ref = 1; 00272 00273 nsIDOMNodeList_AddRef(nslist); 00274 ret->nslist = nslist; 00275 ret->doc = doc; 00276 00277 init_dispex(&ret->dispex, (IUnknown*)HTMLCHILDCOL(ret), &HTMLDOMChildrenCollection_dispex); 00278 00279 return HTMLCHILDCOL(ret); 00280 } 00281 00282 #define HTMLDOMNODE_THIS(iface) DEFINE_THIS(HTMLDOMNode, HTMLDOMNode, iface) 00283 00284 static HRESULT WINAPI HTMLDOMNode_QueryInterface(IHTMLDOMNode *iface, 00285 REFIID riid, void **ppv) 00286 { 00287 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00288 00289 return This->vtbl->qi(This, riid, ppv); 00290 } 00291 00292 static ULONG WINAPI HTMLDOMNode_AddRef(IHTMLDOMNode *iface) 00293 { 00294 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00295 LONG ref = InterlockedIncrement(&This->ref); 00296 00297 TRACE("(%p) ref=%d\n", This, ref); 00298 00299 return ref; 00300 } 00301 00302 static ULONG WINAPI HTMLDOMNode_Release(IHTMLDOMNode *iface) 00303 { 00304 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00305 LONG ref = InterlockedDecrement(&This->ref); 00306 00307 TRACE("(%p) ref=%d\n", This, ref); 00308 00309 if(!ref) { 00310 This->vtbl->destructor(This); 00311 release_dispex(&This->dispex); 00312 heap_free(This); 00313 } 00314 00315 return ref; 00316 } 00317 00318 static HRESULT WINAPI HTMLDOMNode_GetTypeInfoCount(IHTMLDOMNode *iface, UINT *pctinfo) 00319 { 00320 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00321 return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); 00322 } 00323 00324 static HRESULT WINAPI HTMLDOMNode_GetTypeInfo(IHTMLDOMNode *iface, UINT iTInfo, 00325 LCID lcid, ITypeInfo **ppTInfo) 00326 { 00327 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00328 return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); 00329 } 00330 00331 static HRESULT WINAPI HTMLDOMNode_GetIDsOfNames(IHTMLDOMNode *iface, REFIID riid, 00332 LPOLESTR *rgszNames, UINT cNames, 00333 LCID lcid, DISPID *rgDispId) 00334 { 00335 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00336 return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); 00337 } 00338 00339 static HRESULT WINAPI HTMLDOMNode_Invoke(IHTMLDOMNode *iface, DISPID dispIdMember, 00340 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 00341 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 00342 { 00343 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00344 return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, 00345 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 00346 } 00347 00348 static HRESULT WINAPI HTMLDOMNode_get_nodeType(IHTMLDOMNode *iface, LONG *p) 00349 { 00350 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00351 PRUint16 type = -1; 00352 00353 TRACE("(%p)->(%p)\n", This, p); 00354 00355 nsIDOMNode_GetNodeType(This->nsnode, &type); 00356 00357 switch(type) { 00358 case ELEMENT_NODE: 00359 *p = 1; 00360 break; 00361 case TEXT_NODE: 00362 *p = 3; 00363 break; 00364 case COMMENT_NODE: 00365 *p = 8; 00366 break; 00367 case DOCUMENT_NODE: 00368 *p = 9; 00369 break; 00370 default: 00371 /* 00372 * FIXME: 00373 * According to MSDN only ELEMENT_NODE and TEXT_NODE are supported. 00374 * It needs more tests. 00375 */ 00376 FIXME("type %u\n", type); 00377 *p = 0; 00378 } 00379 00380 return S_OK; 00381 } 00382 00383 static HRESULT WINAPI HTMLDOMNode_get_parentNode(IHTMLDOMNode *iface, IHTMLDOMNode **p) 00384 { 00385 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00386 HTMLDOMNode *node; 00387 nsIDOMNode *nsnode; 00388 nsresult nsres; 00389 00390 TRACE("(%p)->(%p)\n", This, p); 00391 00392 nsres = nsIDOMNode_GetParentNode(This->nsnode, &nsnode); 00393 if(NS_FAILED(nsres)) { 00394 ERR("GetParentNode failed: %08x\n", nsres); 00395 return E_FAIL; 00396 } 00397 00398 if(!nsnode) { 00399 *p = NULL; 00400 return S_OK; 00401 } 00402 00403 node = get_node(This->doc, nsnode, TRUE); 00404 *p = HTMLDOMNODE(node); 00405 IHTMLDOMNode_AddRef(*p); 00406 return S_OK; 00407 } 00408 00409 static HRESULT WINAPI HTMLDOMNode_hasChildNodes(IHTMLDOMNode *iface, VARIANT_BOOL *fChildren) 00410 { 00411 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00412 PRBool has_child = FALSE; 00413 nsresult nsres; 00414 00415 TRACE("(%p)->(%p)\n", This, fChildren); 00416 00417 nsres = nsIDOMNode_HasChildNodes(This->nsnode, &has_child); 00418 if(NS_FAILED(nsres)) 00419 ERR("HasChildNodes failed: %08x\n", nsres); 00420 00421 *fChildren = has_child ? VARIANT_TRUE : VARIANT_FALSE; 00422 return S_OK; 00423 } 00424 00425 static HRESULT WINAPI HTMLDOMNode_get_childNodes(IHTMLDOMNode *iface, IDispatch **p) 00426 { 00427 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00428 nsIDOMNodeList *nslist; 00429 nsresult nsres; 00430 00431 TRACE("(%p)->(%p)\n", This, p); 00432 00433 nsres = nsIDOMNode_GetChildNodes(This->nsnode, &nslist); 00434 if(NS_FAILED(nsres)) { 00435 ERR("GetChildNodes failed: %08x\n", nsres); 00436 return E_FAIL; 00437 } 00438 00439 *p = (IDispatch*)create_child_collection(This->doc, nslist); 00440 nsIDOMNodeList_Release(nslist); 00441 00442 return S_OK; 00443 } 00444 00445 static HRESULT WINAPI HTMLDOMNode_get_attributes(IHTMLDOMNode *iface, IDispatch **p) 00446 { 00447 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00448 FIXME("(%p)->(%p)\n", This, p); 00449 return E_NOTIMPL; 00450 } 00451 00452 static HRESULT WINAPI HTMLDOMNode_insertBefore(IHTMLDOMNode *iface, IHTMLDOMNode *newChild, 00453 VARIANT refChild, IHTMLDOMNode **node) 00454 { 00455 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00456 nsIDOMNode *nsnode, *nsref = NULL; 00457 HTMLDOMNode *new_child; 00458 nsresult nsres; 00459 00460 TRACE("(%p)->(%p %s %p)\n", This, newChild, debugstr_variant(&refChild), node); 00461 00462 new_child = get_node_obj(This->doc, (IUnknown*)newChild); 00463 if(!new_child) { 00464 ERR("invalid newChild\n"); 00465 return E_INVALIDARG; 00466 } 00467 00468 switch(V_VT(&refChild)) { 00469 case VT_NULL: 00470 break; 00471 case VT_DISPATCH: { 00472 HTMLDOMNode *ref_node; 00473 00474 ref_node = get_node_obj(This->doc, (IUnknown*)V_DISPATCH(&refChild)); 00475 if(!ref_node) { 00476 ERR("unvalid node\n"); 00477 return E_FAIL; 00478 } 00479 00480 nsref = ref_node->nsnode; 00481 break; 00482 } 00483 default: 00484 FIXME("unimplemented vt %d\n", V_VT(&refChild)); 00485 return E_NOTIMPL; 00486 } 00487 00488 nsres = nsIDOMNode_InsertBefore(This->nsnode, new_child->nsnode, nsref, &nsnode); 00489 if(NS_FAILED(nsres)) { 00490 ERR("InsertBefore failed: %08x\n", nsres); 00491 return E_FAIL; 00492 } 00493 00494 *node = HTMLDOMNODE(get_node(This->doc, nsnode, TRUE)); 00495 nsIDOMNode_Release(nsnode); 00496 IHTMLDOMNode_AddRef(*node); 00497 return S_OK; 00498 } 00499 00500 static HRESULT WINAPI HTMLDOMNode_removeChild(IHTMLDOMNode *iface, IHTMLDOMNode *oldChild, 00501 IHTMLDOMNode **node) 00502 { 00503 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00504 HTMLDOMNode *node_obj; 00505 nsIDOMNode *nsnode; 00506 nsresult nsres; 00507 00508 TRACE("(%p)->(%p %p)\n", This, oldChild, node); 00509 00510 node_obj = get_node_obj(This->doc, (IUnknown*)oldChild); 00511 if(!node_obj) 00512 return E_FAIL; 00513 00514 nsres = nsIDOMNode_RemoveChild(This->nsnode, node_obj->nsnode, &nsnode); 00515 if(NS_FAILED(nsres)) { 00516 ERR("RemoveChild failed: %08x\n", nsres); 00517 return E_FAIL; 00518 } 00519 00520 /* FIXME: Make sure that node != newChild */ 00521 *node = HTMLDOMNODE(get_node(This->doc, nsnode, TRUE)); 00522 nsIDOMNode_Release(nsnode); 00523 IHTMLDOMNode_AddRef(*node); 00524 return S_OK; 00525 } 00526 00527 static HRESULT WINAPI HTMLDOMNode_replaceChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild, 00528 IHTMLDOMNode *oldChild, IHTMLDOMNode **node) 00529 { 00530 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00531 FIXME("(%p)->(%p %p %p)\n", This, newChild, oldChild, node); 00532 return E_NOTIMPL; 00533 } 00534 00535 static HRESULT WINAPI HTMLDOMNode_cloneNode(IHTMLDOMNode *iface, VARIANT_BOOL fDeep, 00536 IHTMLDOMNode **clonedNode) 00537 { 00538 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00539 nsIDOMNode *nsnode; 00540 HTMLDOMNode *node; 00541 nsresult nsres; 00542 00543 TRACE("(%p)->(%x %p)\n", This, fDeep, clonedNode); 00544 00545 nsres = nsIDOMNode_CloneNode(This->nsnode, fDeep != VARIANT_FALSE, &nsnode); 00546 if(NS_FAILED(nsres) || !nsnode) { 00547 ERR("CloneNode failed: %08x\n", nsres); 00548 return E_FAIL; 00549 } 00550 00551 node = get_node(This->doc, nsnode, TRUE); 00552 IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); 00553 *clonedNode = HTMLDOMNODE(node); 00554 return S_OK; 00555 } 00556 00557 static HRESULT WINAPI HTMLDOMNode_removeNode(IHTMLDOMNode *iface, VARIANT_BOOL fDeep, 00558 IHTMLDOMNode **removed) 00559 { 00560 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00561 FIXME("(%p)->(%x %p)\n", This, fDeep, removed); 00562 return E_NOTIMPL; 00563 } 00564 00565 static HRESULT WINAPI HTMLDOMNode_swapNode(IHTMLDOMNode *iface, IHTMLDOMNode *otherNode, 00566 IHTMLDOMNode **swappedNode) 00567 { 00568 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00569 FIXME("(%p)->(%p %p)\n", This, otherNode, swappedNode); 00570 return E_NOTIMPL; 00571 } 00572 00573 static HRESULT WINAPI HTMLDOMNode_replaceNode(IHTMLDOMNode *iface, IHTMLDOMNode *replacement, 00574 IHTMLDOMNode **replaced) 00575 { 00576 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00577 FIXME("(%p)->(%p %p)\n", This, replacement, replaced); 00578 return E_NOTIMPL; 00579 } 00580 00581 static HRESULT WINAPI HTMLDOMNode_appendChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild, 00582 IHTMLDOMNode **node) 00583 { 00584 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00585 HTMLDOMNode *node_obj; 00586 nsIDOMNode *nsnode; 00587 nsresult nsres; 00588 00589 TRACE("(%p)->(%p %p)\n", This, newChild, node); 00590 00591 node_obj = get_node_obj(This->doc, (IUnknown*)newChild); 00592 if(!node_obj) 00593 return E_FAIL; 00594 00595 nsres = nsIDOMNode_AppendChild(This->nsnode, node_obj->nsnode, &nsnode); 00596 if(NS_FAILED(nsres)) { 00597 WARN("AppendChild failed: %08x\n", nsres); 00598 nsnode = node_obj->nsnode; 00599 } 00600 00601 /* FIXME: Make sure that node != newChild */ 00602 *node = HTMLDOMNODE(get_node(This->doc, nsnode, TRUE)); 00603 IHTMLDOMNode_AddRef(*node); 00604 return S_OK; 00605 } 00606 00607 static HRESULT WINAPI HTMLDOMNode_get_nodeName(IHTMLDOMNode *iface, BSTR *p) 00608 { 00609 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00610 00611 TRACE("(%p)->(%p)\n", This, p); 00612 00613 *p = NULL; 00614 00615 if(This->nsnode) { 00616 nsAString name_str; 00617 const PRUnichar *name; 00618 nsresult nsres; 00619 00620 nsAString_Init(&name_str, NULL); 00621 nsres = nsIDOMNode_GetNodeName(This->nsnode, &name_str); 00622 00623 if(NS_SUCCEEDED(nsres)) { 00624 nsAString_GetData(&name_str, &name); 00625 *p = SysAllocString(name); 00626 }else { 00627 ERR("GetNodeName failed: %08x\n", nsres); 00628 } 00629 00630 nsAString_Finish(&name_str); 00631 } 00632 00633 return S_OK; 00634 } 00635 00636 static HRESULT WINAPI HTMLDOMNode_put_nodeValue(IHTMLDOMNode *iface, VARIANT v) 00637 { 00638 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00639 00640 TRACE("(%p)->()\n", This); 00641 00642 switch(V_VT(&v)) { 00643 case VT_BSTR: { 00644 nsAString val_str; 00645 00646 TRACE("bstr %s\n", debugstr_w(V_BSTR(&v))); 00647 00648 nsAString_InitDepend(&val_str, V_BSTR(&v)); 00649 nsIDOMNode_SetNodeValue(This->nsnode, &val_str); 00650 nsAString_Finish(&val_str); 00651 00652 return S_OK; 00653 } 00654 00655 default: 00656 FIXME("unsupported vt %d\n", V_VT(&v)); 00657 } 00658 00659 return E_NOTIMPL; 00660 } 00661 00662 static HRESULT WINAPI HTMLDOMNode_get_nodeValue(IHTMLDOMNode *iface, VARIANT *p) 00663 { 00664 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00665 const PRUnichar *val; 00666 nsAString val_str; 00667 00668 TRACE("(%p)->(%p)\n", This, p); 00669 00670 nsAString_Init(&val_str, NULL); 00671 nsIDOMNode_GetNodeValue(This->nsnode, &val_str); 00672 nsAString_GetData(&val_str, &val); 00673 00674 if(*val) { 00675 V_VT(p) = VT_BSTR; 00676 V_BSTR(p) = SysAllocString(val); 00677 }else { 00678 V_VT(p) = VT_NULL; 00679 } 00680 00681 nsAString_Finish(&val_str); 00682 00683 return S_OK; 00684 } 00685 00686 static HRESULT WINAPI HTMLDOMNode_get_firstChild(IHTMLDOMNode *iface, IHTMLDOMNode **p) 00687 { 00688 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00689 nsIDOMNode *nschild = NULL; 00690 00691 TRACE("(%p)->(%p)\n", This, p); 00692 00693 nsIDOMNode_GetFirstChild(This->nsnode, &nschild); 00694 if(nschild) { 00695 *p = HTMLDOMNODE(get_node(This->doc, nschild, TRUE)); 00696 IHTMLDOMNode_AddRef(*p); 00697 }else { 00698 *p = NULL; 00699 } 00700 00701 return S_OK; 00702 } 00703 00704 static HRESULT WINAPI HTMLDOMNode_get_lastChild(IHTMLDOMNode *iface, IHTMLDOMNode **p) 00705 { 00706 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00707 nsIDOMNode *nschild = NULL; 00708 00709 TRACE("(%p)->(%p)\n", This, p); 00710 00711 nsIDOMNode_GetLastChild(This->nsnode, &nschild); 00712 if(nschild) { 00713 *p = HTMLDOMNODE(get_node(This->doc, nschild, TRUE)); 00714 IHTMLDOMNode_AddRef(*p); 00715 }else { 00716 *p = NULL; 00717 } 00718 00719 return S_OK; 00720 } 00721 00722 static HRESULT WINAPI HTMLDOMNode_get_previousSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p) 00723 { 00724 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00725 FIXME("(%p)->(%p)\n", This, p); 00726 return E_NOTIMPL; 00727 } 00728 00729 static HRESULT WINAPI HTMLDOMNode_get_nextSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p) 00730 { 00731 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); 00732 nsIDOMNode *nssibling = NULL; 00733 00734 TRACE("(%p)->(%p)\n", This, p); 00735 00736 nsIDOMNode_GetNextSibling(This->nsnode, &nssibling); 00737 if(nssibling) { 00738 *p = HTMLDOMNODE(get_node(This->doc, nssibling, TRUE)); 00739 IHTMLDOMNode_AddRef(*p); 00740 }else { 00741 *p = NULL; 00742 } 00743 00744 return S_OK; 00745 } 00746 00747 #undef HTMLDOMNODE_THIS 00748 00749 static const IHTMLDOMNodeVtbl HTMLDOMNodeVtbl = { 00750 HTMLDOMNode_QueryInterface, 00751 HTMLDOMNode_AddRef, 00752 HTMLDOMNode_Release, 00753 HTMLDOMNode_GetTypeInfoCount, 00754 HTMLDOMNode_GetTypeInfo, 00755 HTMLDOMNode_GetIDsOfNames, 00756 HTMLDOMNode_Invoke, 00757 HTMLDOMNode_get_nodeType, 00758 HTMLDOMNode_get_parentNode, 00759 HTMLDOMNode_hasChildNodes, 00760 HTMLDOMNode_get_childNodes, 00761 HTMLDOMNode_get_attributes, 00762 HTMLDOMNode_insertBefore, 00763 HTMLDOMNode_removeChild, 00764 HTMLDOMNode_replaceChild, 00765 HTMLDOMNode_cloneNode, 00766 HTMLDOMNode_removeNode, 00767 HTMLDOMNode_swapNode, 00768 HTMLDOMNode_replaceNode, 00769 HTMLDOMNode_appendChild, 00770 HTMLDOMNode_get_nodeName, 00771 HTMLDOMNode_put_nodeValue, 00772 HTMLDOMNode_get_nodeValue, 00773 HTMLDOMNode_get_firstChild, 00774 HTMLDOMNode_get_lastChild, 00775 HTMLDOMNode_get_previousSibling, 00776 HTMLDOMNode_get_nextSibling 00777 }; 00778 00779 #define HTMLDOMNODE2_THIS(iface) DEFINE_THIS(HTMLDOMNode, HTMLDOMNode2, iface) 00780 00781 static HRESULT WINAPI HTMLDOMNode2_QueryInterface(IHTMLDOMNode2 *iface, 00782 REFIID riid, void **ppv) 00783 { 00784 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00785 00786 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(This), riid, ppv); 00787 } 00788 00789 static ULONG WINAPI HTMLDOMNode2_AddRef(IHTMLDOMNode2 *iface) 00790 { 00791 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00792 00793 return IHTMLDOMNode_AddRef(HTMLDOMNODE(This)); 00794 } 00795 00796 static ULONG WINAPI HTMLDOMNode2_Release(IHTMLDOMNode2 *iface) 00797 { 00798 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00799 00800 return IHTMLDOMNode_Release(HTMLDOMNODE(This)); 00801 } 00802 00803 static HRESULT WINAPI HTMLDOMNode2_GetTypeInfoCount(IHTMLDOMNode2 *iface, UINT *pctinfo) 00804 { 00805 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00806 return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); 00807 } 00808 00809 static HRESULT WINAPI HTMLDOMNode2_GetTypeInfo(IHTMLDOMNode2 *iface, UINT iTInfo, 00810 LCID lcid, ITypeInfo **ppTInfo) 00811 { 00812 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00813 return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); 00814 } 00815 00816 static HRESULT WINAPI HTMLDOMNode2_GetIDsOfNames(IHTMLDOMNode2 *iface, REFIID riid, 00817 LPOLESTR *rgszNames, UINT cNames, 00818 LCID lcid, DISPID *rgDispId) 00819 { 00820 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00821 return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); 00822 } 00823 00824 static HRESULT WINAPI HTMLDOMNode2_Invoke(IHTMLDOMNode2 *iface, DISPID dispIdMember, 00825 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 00826 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 00827 { 00828 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00829 return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, 00830 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 00831 } 00832 00833 static HRESULT WINAPI HTMLDOMNode2_get_ownerDocument(IHTMLDOMNode2 *iface, IDispatch **p) 00834 { 00835 HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); 00836 00837 TRACE("(%p)->(%p)\n", This, p); 00838 00839 /* FIXME: Better check for document node */ 00840 if(This == &This->doc->node) { 00841 *p = NULL; 00842 }else { 00843 *p = (IDispatch*)HTMLDOC(&This->doc->basedoc); 00844 IDispatch_AddRef(*p); 00845 } 00846 return S_OK; 00847 } 00848 00849 #undef HTMLDOMNODE2_THIS 00850 00851 static const IHTMLDOMNode2Vtbl HTMLDOMNode2Vtbl = { 00852 HTMLDOMNode2_QueryInterface, 00853 HTMLDOMNode2_AddRef, 00854 HTMLDOMNode2_Release, 00855 HTMLDOMNode2_GetTypeInfoCount, 00856 HTMLDOMNode2_GetTypeInfo, 00857 HTMLDOMNode2_GetIDsOfNames, 00858 HTMLDOMNode2_Invoke, 00859 HTMLDOMNode2_get_ownerDocument 00860 }; 00861 00862 HRESULT HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid, void **ppv) 00863 { 00864 *ppv = NULL; 00865 00866 if(IsEqualGUID(&IID_IUnknown, riid)) { 00867 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 00868 *ppv = HTMLDOMNODE(This); 00869 }else if(IsEqualGUID(&IID_IDispatch, riid)) { 00870 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); 00871 *ppv = HTMLDOMNODE(This); 00872 }else if(IsEqualGUID(&IID_IDispatchEx, riid)) { 00873 if(This->dispex.data) { 00874 TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv); 00875 *ppv = DISPATCHEX(&This->dispex); 00876 }else { 00877 FIXME("(%p)->(IID_IDispatchEx %p)\n", This, ppv); 00878 return E_NOINTERFACE; 00879 } 00880 }else if(IsEqualGUID(&IID_IHTMLDOMNode, riid)) { 00881 TRACE("(%p)->(IID_IHTMLDOMNode %p)\n", This, ppv); 00882 *ppv = HTMLDOMNODE(This); 00883 }else if(IsEqualGUID(&IID_IHTMLDOMNode2, riid)) { 00884 TRACE("(%p)->(IID_IHTMLDOMNode2 %p)\n", This, ppv); 00885 *ppv = HTMLDOMNODE2(This); 00886 }else if(dispex_query_interface(&This->dispex, riid, ppv)) { 00887 return *ppv ? S_OK : E_NOINTERFACE; 00888 } 00889 00890 if(*ppv) { 00891 IUnknown_AddRef((IUnknown*)*ppv); 00892 return S_OK; 00893 } 00894 00895 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 00896 return E_NOINTERFACE; 00897 } 00898 00899 void HTMLDOMNode_destructor(HTMLDOMNode *This) 00900 { 00901 if(This->nsnode) 00902 nsIDOMNode_Release(This->nsnode); 00903 if(This->event_target) 00904 release_event_target(This->event_target); 00905 } 00906 00907 static const NodeImplVtbl HTMLDOMNodeImplVtbl = { 00908 HTMLDOMNode_QI, 00909 HTMLDOMNode_destructor 00910 }; 00911 00912 void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsnode) 00913 { 00914 node->lpHTMLDOMNodeVtbl = &HTMLDOMNodeVtbl; 00915 node->lpHTMLDOMNode2Vtbl = &HTMLDOMNode2Vtbl; 00916 node->ref = 1; 00917 node->doc = doc; 00918 00919 if(nsnode) 00920 nsIDOMNode_AddRef(nsnode); 00921 node->nsnode = nsnode; 00922 00923 node->next = doc->nodes; 00924 doc->nodes = node; 00925 } 00926 00927 static HTMLDOMNode *create_node(HTMLDocumentNode *doc, nsIDOMNode *nsnode) 00928 { 00929 HTMLDOMNode *ret; 00930 PRUint16 node_type; 00931 00932 nsIDOMNode_GetNodeType(nsnode, &node_type); 00933 00934 switch(node_type) { 00935 case ELEMENT_NODE: 00936 ret = &HTMLElement_Create(doc, nsnode, FALSE)->node; 00937 break; 00938 case TEXT_NODE: 00939 ret = HTMLDOMTextNode_Create(doc, nsnode); 00940 break; 00941 case COMMENT_NODE: 00942 ret = &HTMLCommentElement_Create(doc, nsnode)->node; 00943 break; 00944 default: 00945 ret = heap_alloc_zero(sizeof(HTMLDOMNode)); 00946 ret->vtbl = &HTMLDOMNodeImplVtbl; 00947 HTMLDOMNode_Init(doc, ret, nsnode); 00948 } 00949 00950 TRACE("type %d ret %p\n", node_type, ret); 00951 00952 return ret; 00953 } 00954 00955 /* 00956 * FIXME 00957 * List looks really ugly here. We should use a better data structure or 00958 * (better) find a way to store HTMLDOMelement pointer in nsIDOMNode. 00959 */ 00960 00961 HTMLDOMNode *get_node(HTMLDocumentNode *This, nsIDOMNode *nsnode, BOOL create) 00962 { 00963 HTMLDOMNode *iter = This->nodes; 00964 00965 while(iter) { 00966 if(iter->nsnode == nsnode) 00967 break; 00968 iter = iter->next; 00969 } 00970 00971 if(iter || !create) 00972 return iter; 00973 00974 return create_node(This, nsnode); 00975 } 00976 00977 /* 00978 * FIXME 00979 * We should use better way for getting node object (like private interface) 00980 * or avoid it at all. 00981 */ 00982 static HTMLDOMNode *get_node_obj(HTMLDocumentNode *This, IUnknown *iface) 00983 { 00984 HTMLDOMNode *iter = This->nodes; 00985 IHTMLDOMNode *node; 00986 00987 IUnknown_QueryInterface(iface, &IID_IHTMLDOMNode, (void**)&node); 00988 IHTMLDOMNode_Release(node); 00989 00990 while(iter) { 00991 if(HTMLDOMNODE(iter) == node) 00992 return iter; 00993 iter = iter->next; 00994 } 00995 00996 FIXME("Not found %p\n", iface); 00997 return NULL; 00998 } 00999 01000 void release_nodes(HTMLDocumentNode *This) 01001 { 01002 HTMLDOMNode *iter, *next; 01003 01004 if(!This->nodes) 01005 return; 01006 01007 for(iter = This->nodes; iter; iter = next) { 01008 next = iter->next; 01009 iter->doc = NULL; 01010 if(&This->node != iter) 01011 IHTMLDOMNode_Release(HTMLDOMNODE(iter)); 01012 } 01013 } Generated on Sun May 27 2012 04:24:58 for ReactOS by
1.7.6.1
|