Back to index

lightning-sunbird  0.9+nobinonly
IEHtmlNode.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Adam Lock <adamlock@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "stdafx.h"
00040 #include "IEHtmlNode.h"
00041 
00042 #include "plhash.h"
00043 
00044 static PLHashTable *g_NodeLookupTable;
00045 
00046 static PLHashNumber PR_CALLBACK HashFunction(const void *key)
00047 {
00048     return (PRUint32) key;
00049 }
00050 
00051 PRIntn PR_CALLBACK HashComparator(const void *v1, const void *v2)
00052 {
00053     if (v1 == v2)
00054     {
00055         return 1;
00056     }
00057     return 0;
00058 }
00059 
00060 
00061 CNode::CNode() :
00062     mParent(NULL),mDOMNode(NULL)
00063 {
00064 }
00065 
00066 CNode::~CNode()
00067 {
00068 }
00069 
00070 
00071 HRESULT CNode::SetParent(CNode *pParent)
00072 {
00073     mParent = pParent;
00074     return S_OK;
00075 }
00076 
00077 
00078 HRESULT CNode::FindFromDOMNode(nsIDOMNode *pIDOMNode, CNode **pNode)
00079 {
00080     if (pIDOMNode == nsnull)
00081     {
00082         return E_FAIL;
00083     }
00084 
00085     if (g_NodeLookupTable == NULL)
00086     {
00087         return E_FAIL;
00088     }
00089 
00090     nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(pIDOMNode);
00091     *pNode = (CNode *) PL_HashTableLookup(g_NodeLookupTable, nodeAsSupports);
00092 
00093     return S_OK;
00094 }
00095 
00096 HRESULT CNode::SetDOMNode(nsIDOMNode *pIDOMNode)
00097 {
00098     if (pIDOMNode)
00099     {
00100         if (g_NodeLookupTable == NULL)
00101         {
00102             g_NodeLookupTable = PL_NewHashTable(123, HashFunction, HashComparator, HashComparator, NULL, NULL);
00103         }
00104 
00105         mDOMNode = pIDOMNode;
00106         nsCOMPtr<nsISupports> nodeAsSupports= do_QueryInterface(mDOMNode);
00107         PL_HashTableAdd(g_NodeLookupTable, nodeAsSupports, this);
00108     }
00109     else if (mDOMNode)
00110     {
00111         // Remove the entry from the hashtable
00112         nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(mDOMNode);
00113         PL_HashTableRemove(g_NodeLookupTable, nodeAsSupports);
00114         mDOMNode = nsnull;
00115 
00116         if (g_NodeLookupTable->nentries == 0)
00117         {
00118             PL_HashTableDestroy(g_NodeLookupTable);
00119             g_NodeLookupTable = NULL;
00120         }
00121     }
00122     return S_OK;
00123 }
00124 
00126 // CIEHtmlDomNode methods
00127 
00128 #include "nsIDOMHTMLButtonElement.h"
00129 #include "nsIDOMHTMLElement.h"
00130 
00131 #include "IEHtmlButtonElement.h"
00132 #include "IEHtmlElement.h"
00133 
00134 CIEHtmlDomNode::CIEHtmlDomNode()
00135 {
00136 }
00137 
00138 CIEHtmlDomNode::~CIEHtmlDomNode()
00139 {
00140     SetDOMNode(nsnull);
00141 }
00142 
00143 #define CREATE_FROM_DOMNODE(nsInterface, WrapperType, errorMsg) \
00144     nsCOMPtr<nsInterface> domNode_##nsInterface = do_QueryInterface(pIDOMNode); \
00145     if (domNode_##nsInterface) \
00146     { \
00147         WrapperType *pWrapper = NULL; \
00148         WrapperType::CreateInstance(&pWrapper); \
00149         if (!pWrapper) \
00150         { \
00151             NS_ASSERTION(0, errorMsg); \
00152             return E_OUTOFMEMORY; \
00153         } \
00154         if (FAILED(pWrapper->QueryInterface(IID_IUnknown, (void**)pNode))) \
00155             return E_UNEXPECTED; \
00156         pWrapper->SetDOMNode(pIDOMNode); \
00157         return S_OK; \
00158     }
00159 
00160 
00161 HRESULT CIEHtmlDomNode::CreateFromDOMNode(nsIDOMNode *pIDOMNode, IUnknown **pNode)
00162 {
00163     CREATE_FROM_DOMNODE(nsIDOMHTMLButtonElement, CIEHtmlButtonElementInstance, "")
00164     CREATE_FROM_DOMNODE(nsIDOMHTMLElement, CIEHtmlElementInstance, "Could not create element")
00165     CREATE_FROM_DOMNODE(nsIDOMNode, CIEHtmlDomNodeInstance, "Could not create node")
00166     return E_FAIL;
00167 }
00168 
00169 HRESULT CIEHtmlDomNode::FindFromDOMNode(nsIDOMNode *pIDOMNode, IUnknown **pNode)
00170 {
00171     if (pIDOMNode == nsnull)
00172     {
00173         return E_FAIL;
00174     }
00175 
00176     if (g_NodeLookupTable == NULL)
00177     {
00178         return E_FAIL;
00179     }
00180 
00181     nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(pIDOMNode);
00182     *pNode = (IUnknown *) PL_HashTableLookup(g_NodeLookupTable, nodeAsSupports);
00183 
00184     return S_OK;
00185 }
00186 
00187 HRESULT CIEHtmlDomNode::FindOrCreateFromDOMNode(nsIDOMNode *pIDOMNode, IUnknown **pNode)
00188 {
00189     FindFromDOMNode(pIDOMNode,pNode);
00190 
00191     if (*pNode)
00192     {
00193         (*pNode)->AddRef();
00194         return S_OK;
00195     }
00196 
00197     HRESULT hr = CreateFromDOMNode(pIDOMNode, pNode);
00198     if SUCCEEDED(hr)
00199         return S_OK;
00200     return hr;
00201 }
00202 
00203 HRESULT CIEHtmlDomNode::SetDOMNode(nsIDOMNode *pIDOMNode)
00204 {
00205     if (pIDOMNode)
00206     {
00207         if (g_NodeLookupTable == NULL)
00208         {
00209             g_NodeLookupTable = PL_NewHashTable(123, HashFunction, HashComparator, HashComparator, NULL, NULL);
00210         }
00211         
00212         mDOMNode = pIDOMNode;
00213         nsCOMPtr<nsISupports> nodeAsSupports= do_QueryInterface(mDOMNode);
00214         PL_HashTableAdd(g_NodeLookupTable, nodeAsSupports, (IUnknown *)this );
00215     }
00216     else if (mDOMNode)
00217     {    
00218         // Remove the entry from the hashtable
00219         nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(mDOMNode);
00220         PL_HashTableRemove(g_NodeLookupTable, nodeAsSupports);
00221         mDOMNode = nsnull;
00222 
00223         if (g_NodeLookupTable->nentries == 0)
00224         {
00225             PL_HashTableDestroy(g_NodeLookupTable);
00226             g_NodeLookupTable = NULL;
00227         }    
00228     }
00229     return S_OK;
00230 }
00231 
00233 // IHTMLDOMNode methods
00234 
00235 #define SIB_NODE_GET_NUMERIC(function,numtype) \
00236 { \
00237   if (!p) return E_INVALIDARG; \
00238   if (!mDOMNode) return E_UNEXPECTED; \
00239   numtype nData; \
00240   HRESULT rc = mDOMNode->function(&nData); \
00241   *p=nData; \
00242   return rc; \
00243 }
00244 
00245 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nodeType(long __RPC_FAR *p)
00246   SIB_NODE_GET_NUMERIC(GetNodeType,PRUint16)
00247 
00248 #define SIB_NODE_GET_ELEMENT(function,fn_elt_type) \
00249 { \
00250     return E_NOTIMPL; \
00251 }
00252 
00253 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_parentNode(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
00254   SIB_NODE_GET_ELEMENT(GetParentNode,nsIDOMNode)
00255 
00256 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::hasChildNodes(VARIANT_BOOL __RPC_FAR *p)
00257   SIB_NODE_GET_NUMERIC(HasChildNodes,PRBool)
00258 
00259 #define SIB_STD_NOTIMPL \
00260 { \
00261   return E_NOTIMPL; \
00262 }
00263 
00264 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_childNodes(IDispatch __RPC_FAR *__RPC_FAR *p)
00265   SIB_STD_NOTIMPL
00266 
00267 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_attributes(IDispatch __RPC_FAR *__RPC_FAR *p)
00268   SIB_STD_NOTIMPL
00269 
00270 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::insertBefore(IHTMLDOMNode __RPC_FAR *newChild,
00271     VARIANT refChild,
00272     IHTMLDOMNode __RPC_FAR *__RPC_FAR *node)
00273   SIB_STD_NOTIMPL
00274 
00275 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::removeChild(
00276     IHTMLDOMNode __RPC_FAR *oldChild,
00277     IHTMLDOMNode __RPC_FAR *__RPC_FAR *node)
00278   SIB_STD_NOTIMPL
00279 
00280 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::replaceChild(
00281     IHTMLDOMNode __RPC_FAR *newChild,
00282     IHTMLDOMNode __RPC_FAR *oldChild,
00283     IHTMLDOMNode __RPC_FAR *__RPC_FAR *node)
00284   SIB_STD_NOTIMPL
00285 
00286 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::cloneNode( 
00287     VARIANT_BOOL fDeep,
00288     IHTMLDOMNode __RPC_FAR *__RPC_FAR *clonedNode)
00289   SIB_STD_NOTIMPL
00290 
00291 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::removeNode( 
00292     VARIANT_BOOL fDeep,
00293     IHTMLDOMNode __RPC_FAR *__RPC_FAR *removed)
00294   SIB_STD_NOTIMPL
00295 
00296 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::swapNode( 
00297     IHTMLDOMNode __RPC_FAR *otherNode,
00298     IHTMLDOMNode __RPC_FAR *__RPC_FAR *swappedNode)
00299   SIB_STD_NOTIMPL
00300 
00301 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::replaceNode( 
00302     IHTMLDOMNode __RPC_FAR *replacement,
00303     IHTMLDOMNode __RPC_FAR *__RPC_FAR *replaced)
00304   SIB_STD_NOTIMPL
00305 
00306 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::appendChild(IHTMLDOMNode *newChild, IHTMLDOMNode **node)
00307 {
00308     if (!newChild || !node)
00309         return E_INVALIDARG;
00310     *node = NULL;
00311     if (!mDOMNode)
00312         return E_UNEXPECTED;
00313     nsCOMPtr<nsIDOMNode> domNode;
00314     nsresult rv = mDOMNode->AppendChild(((CIEHtmlDomNode*)newChild)->mDOMNode, getter_AddRefs(domNode));
00315     if (NS_FAILED(rv))
00316         return E_FAIL;
00317     // Create com object:
00318     CComPtr<IUnknown> pNode = NULL;
00319     HRESULT hr = CIEHtmlDomNode::FindOrCreateFromDOMNode(domNode, &pNode);
00320     if (FAILED(hr))
00321         return hr;
00322     if (FAILED(pNode->QueryInterface(__uuidof(IHTMLDOMNode), (void**)node)))
00323         return E_UNEXPECTED;
00324     return S_OK;
00325 }
00326 
00327 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nodeName(BSTR __RPC_FAR *p)
00328 {
00329   if (!mDOMNode) return E_UNEXPECTED;
00330   nsString szTagName;
00331   HRESULT rc = mDOMNode->GetNodeName(szTagName);
00332   USES_CONVERSION;
00333   *p = SysAllocString(W2COLE(ToNewUnicode(szTagName)));
00334   return rc;
00335 }
00336 
00337 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::put_nodeValue(VARIANT p)
00338 {
00339   if (!mDOMNode) return E_UNEXPECTED;
00340   CComVariant vValue;
00341   if (FAILED(vValue.ChangeType(VT_BSTR, &p))) {
00342     return E_INVALIDARG;
00343   }
00344   nsString szValue(OLE2W(vValue.bstrVal));
00345   if (!mDOMNode->SetNodeValue(szValue))
00346     return E_FAIL;
00347   return S_OK;
00348 }
00349 
00350 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nodeValue(VARIANT __RPC_FAR *p)
00351 {
00352   if (p == NULL) {
00353     return E_INVALIDARG;
00354   }
00355   if (!mDOMNode) return E_UNEXPECTED;
00356   nsString szValue;
00357   nsresult nr = mDOMNode->GetNodeValue(szValue);
00358   if (nr == NS_OK) {
00359     USES_CONVERSION;
00360     p->vt = VT_BSTR;
00361     p->bstrVal = SysAllocString(W2COLE(ToNewUnicode(szValue)));
00362     return S_OK;
00363   }
00364   return E_FAIL;
00365 }
00366 
00367 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_firstChild(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
00368   SIB_NODE_GET_ELEMENT(GetFirstChild,nsIDOMNode)
00369 
00370 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_lastChild(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
00371   SIB_NODE_GET_ELEMENT(GetLastChild,nsIDOMNode)
00372 
00373 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_previousSibling(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
00374 {
00375   return E_NOTIMPL;
00376 }
00377 
00378 HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nextSibling(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
00379 {
00380   return E_NOTIMPL;
00381 }