ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

htmlnode.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.