This commit is contained in:
locka%iol.ie 2002-09-28 14:32:14 +00:00
Родитель 2e33cb369f
Коммит e28f216899
9 изменённых файлов: 361 добавлений и 359 удалений

Просмотреть файл

@ -45,10 +45,9 @@
#include <stack>
CIEHtmlDocument::CIEHtmlDocument()
CIEHtmlDocument::CIEHtmlDocument() :
mControl(NULL)
{
m_pParent = NULL;
m_pNative = nsnull;
}
@ -59,29 +58,13 @@ CIEHtmlDocument::~CIEHtmlDocument()
void CIEHtmlDocument::SetParent(CMozillaBrowser *parent)
{
m_pParent = parent;
mControl = parent;
}
void CIEHtmlDocument::SetNative(nsIDOMHTMLDocument *native)
{
m_pNative = native;
}
HRESULT CIEHtmlDocument::GetIDispatch(IDispatch **pDispatch)
{
if (pDispatch == NULL)
{
return E_INVALIDARG;
}
IDispatch *pDisp = (IDispatch *) this;
NG_ASSERT(pDisp);
pDisp->AddRef();
*pDispatch = pDisp;
return S_OK;
mDOMDocument = native;
}
@ -142,7 +125,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_body(IHTMLElement __RPC_FAR *__RP
nsCOMPtr<nsIDOMHTMLElement> bodyElement;
m_pNative->GetBody(getter_AddRefs(bodyElement));
mDOMDocument->GetBody(getter_AddRefs(bodyElement));
if (bodyElement)
{
nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(bodyElement);
@ -152,7 +135,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_body(IHTMLElement __RPC_FAR *__RP
if (pElement)
{
pElement->SetDOMNode(bodyNode);
pElement->SetParentNode(this);
pElement->SetParent(this);
pElement->QueryInterface(IID_IHTMLElement, (void **) p);
}
}
@ -179,7 +162,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_images(IHTMLElementCollection __R
*p = NULL;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
m_pNative->GetImages(getter_AddRefs(nodeList));
mDOMDocument->GetImages(getter_AddRefs(nodeList));
// Get all elements
CIEHtmlElementCollectionInstance *pCollection = NULL;
@ -204,7 +187,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_applets(IHTMLElementCollection __
*p = NULL;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
m_pNative->GetApplets(getter_AddRefs(nodeList));
mDOMDocument->GetApplets(getter_AddRefs(nodeList));
// Get all elements
CIEHtmlElementCollectionInstance *pCollection = NULL;
@ -229,7 +212,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_links(IHTMLElementCollection __RP
*p = NULL;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
m_pNative->GetLinks(getter_AddRefs(nodeList));
mDOMDocument->GetLinks(getter_AddRefs(nodeList));
// Get all elements
CIEHtmlElementCollectionInstance *pCollection = NULL;
@ -254,7 +237,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_forms(IHTMLElementCollection __RP
*p = NULL;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
m_pNative->GetForms(getter_AddRefs(nodeList));
mDOMDocument->GetForms(getter_AddRefs(nodeList));
// Get all elements
CIEHtmlElementCollectionInstance *pCollection = NULL;
@ -279,7 +262,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_anchors(IHTMLElementCollection __
*p = NULL;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
m_pNative->GetAnchors(getter_AddRefs(nodeList));
mDOMDocument->GetAnchors(getter_AddRefs(nodeList));
// Get all elements
CIEHtmlElementCollectionInstance *pCollection = NULL;
@ -295,10 +278,10 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_anchors(IHTMLElementCollection __
HRESULT STDMETHODCALLTYPE CIEHtmlDocument::put_title(BSTR v)
{
if (m_pNative)
if (mDOMDocument)
{
nsAutoString newTitle((PRUnichar *) v);
m_pNative->SetTitle(newTitle);
mDOMDocument->SetTitle(newTitle);
}
return S_OK;
}
@ -307,7 +290,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::put_title(BSTR v)
HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_title(BSTR __RPC_FAR *p)
{
nsAutoString value;
if (m_pNative == NULL || m_pNative->GetTitle(value))
if (mDOMDocument == NULL || mDOMDocument->GetTitle(value))
{
return E_FAIL;
}
@ -607,14 +590,16 @@ HRESULT CIEHtmlDocument::WriteCommon(SAFEARRAY __RPC_FAR * psarray, int bLn)
for (DWORD i = 0; i < psarray->rgsabound[0].cElements; i++)
{
nsString str;
nsAutoString str;
if (psarray->fFeatures & FADF_BSTR)
{
USES_CONVERSION;
BSTR *bstrArray = (BSTR *) psarray->pvData;
str = nsString(bstrArray[i], SysStringLen(bstrArray[i]));
str = OLE2W(bstrArray[i]);
}
else if (psarray->fFeatures & FADF_VARIANT)
{
USES_CONVERSION;
VARIANT *vArray = (VARIANT *) psarray->pvData;
VARIANT vStr;
VariantInit(&vStr);
@ -624,13 +609,13 @@ HRESULT CIEHtmlDocument::WriteCommon(SAFEARRAY __RPC_FAR * psarray, int bLn)
SafeArrayUnlock(psarray);
return hr;
}
str = nsString(vStr.bstrVal, SysStringLen(vStr.bstrVal));
str = OLE2W(vStr.bstrVal);
VariantClear(&vStr);
}
if (bLn && !i)
{
if (m_pNative->Writeln(str))
if (mDOMDocument->Writeln(str))
{
SafeArrayUnlock(psarray);
return E_FAIL;
@ -638,7 +623,7 @@ HRESULT CIEHtmlDocument::WriteCommon(SAFEARRAY __RPC_FAR * psarray, int bLn)
}
else
{
if (m_pNative->Write(str))
if (mDOMDocument->Write(str))
{
SafeArrayUnlock(psarray);
return E_FAIL;
@ -670,7 +655,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::writeln(SAFEARRAY __RPC_FAR * psarray
HRESULT STDMETHODCALLTYPE CIEHtmlDocument::open(BSTR url, VARIANT name, VARIANT features, VARIANT replace, IDispatch __RPC_FAR *__RPC_FAR *pomWindowResult)
{
if (m_pNative == NULL || m_pNative->Open())
if (mDOMDocument == NULL || mDOMDocument->Open())
{
return E_FAIL;
}
@ -680,7 +665,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::open(BSTR url, VARIANT name, VARIANT
HRESULT STDMETHODCALLTYPE CIEHtmlDocument::close(void)
{
if (m_pNative == NULL || m_pNative->Close())
if (mDOMDocument == NULL || mDOMDocument->Close())
{
return E_FAIL;
}
@ -1013,9 +998,9 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::createStyleSheet(BSTR bstrHref, long
HRESULT STDMETHODCALLTYPE CIEHtmlDocument::QueryStatus(const GUID __RPC_FAR *pguidCmdGroup, ULONG cCmds, OLECMD __RPC_FAR prgCmds[], OLECMDTEXT __RPC_FAR *pCmdText)
{
HRESULT hr = E_NOTIMPL;
if(m_pParent)
if(mControl)
{
hr = m_pParent->QueryStatus(pguidCmdGroup,cCmds,prgCmds,pCmdText);
hr = mControl->QueryStatus(pguidCmdGroup,cCmds,prgCmds,pCmdText);
}
return hr;
}
@ -1024,9 +1009,9 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::QueryStatus(const GUID __RPC_FAR *pgu
HRESULT STDMETHODCALLTYPE CIEHtmlDocument::Exec(const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT __RPC_FAR *pvaIn, VARIANT __RPC_FAR *pvaOut)
{
HRESULT hr = E_NOTIMPL;
if(m_pParent)
if(mControl)
{
hr = m_pParent->Exec(pguidCmdGroup,nCmdID,nCmdexecopt,pvaIn,pvaOut);
hr = mControl->Exec(pguidCmdGroup,nCmdID,nCmdexecopt,pvaIn,pvaOut);
}
return hr;
}

Просмотреть файл

@ -46,9 +46,10 @@
class CMozillaBrowser;
class CIEHtmlDocument : public CIEHtmlNode,
public IDispatchImpl<IHTMLDocument2, &IID_IHTMLDocument2, &LIBID_MSHTML, 4, 0>,
public IOleCommandTarget
class CIEHtmlDocument :
public CIEHtmlNode,
public IDispatchImpl<IHTMLDocument2, &IID_IHTMLDocument2, &LIBID_MSHTML, 4, 0>,
public IOleCommandTarget
{
public:
CIEHtmlDocument();
@ -56,8 +57,8 @@ protected:
virtual ~CIEHtmlDocument();
// Pointer to browser that owns the document
CMozillaBrowser *m_pParent;
nsIDOMHTMLDocument *m_pNative;
CMozillaBrowser *mControl;
nsCOMPtr<nsIDOMHTMLDocument> mDOMDocument;
HRESULT WriteCommon(SAFEARRAY __RPC_FAR * psarray, int bLn);
@ -72,8 +73,6 @@ BEGIN_COM_MAP(CIEHtmlDocument)
COM_INTERFACE_ENTRY(IOleCommandTarget)
END_COM_MAP()
virtual HRESULT GetIDispatch(IDispatch **pDispatch);
// IOleCommandTarget methods
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID __RPC_FAR *pguidCmdGroup, ULONG cCmds, OLECMD __RPC_FAR prgCmds[], OLECMDTEXT __RPC_FAR *pCmdText);
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT __RPC_FAR *pvaIn, VARIANT __RPC_FAR *pvaOut);

Просмотреть файл

@ -52,17 +52,6 @@ CIEHtmlElement::~CIEHtmlElement()
{
}
HRESULT CIEHtmlElement::GetIDispatch(IDispatch **pDispatch)
{
if (pDispatch == NULL)
{
return E_INVALIDARG;
}
return QueryInterface(IID_IDispatch, (void **) pDispatch);
}
HRESULT CIEHtmlElement::GetChildren(CIEHtmlElementCollectionInstance **ppCollection)
{
// Validate parameters
@ -96,9 +85,15 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::setAttribute(BSTR strAttributeName, VA
return E_INVALIDARG;
}
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
if (!element)
{
return E_UNEXPECTED;
}
// Get the name from the BSTR
USES_CONVERSION;
nsString szName(OLE2W(strAttributeName));
nsAutoString name(OLE2W(strAttributeName));
// Get the value from the variant
CComVariant vValue;
@ -106,16 +101,10 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::setAttribute(BSTR strAttributeName, VA
{
return E_INVALIDARG;
}
nsString szValue(OLE2W(vValue.bstrVal));
nsCOMPtr<nsIDOMElement> element;
if (FAILED(GetDOMElement(getter_AddRefs(element))))
{
return E_UNEXPECTED;
}
// Set the attribute
element->SetAttribute(szName, szValue);
nsAutoString value(OLE2W(vValue.bstrVal));
element->SetAttribute(name, value);
return S_OK;
}
@ -134,26 +123,25 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::getAttribute(BSTR strAttributeName, LO
// Get the name from the BSTR
USES_CONVERSION;
nsString szName(OLE2W(strAttributeName));
nsAutoString name(OLE2W(strAttributeName));
nsCOMPtr<nsIDOMElement> element;
if (FAILED(GetDOMElement(getter_AddRefs(element))))
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
if (!element)
{
return E_UNEXPECTED;
}
BOOL bCaseSensitive = (lFlags == VARIANT_TRUE) ? TRUE : FALSE;
nsString szValue;
// Get the attribute
nsresult nr = element->GetAttribute(szName, szValue);
if (nr == NS_OK)
nsAutoString value;
nsresult rv = element->GetAttribute(name, value);
if (NS_SUCCEEDED(rv))
{
USES_CONVERSION;
AttributeValue->vt = VT_BSTR;
AttributeValue->bstrVal = SysAllocString(W2COLE(szValue.get()));
AttributeValue->bstrVal = SysAllocString(W2COLE(value.get()));
return S_OK;
}
else
@ -171,8 +159,8 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::removeAttribute(BSTR strAttributeName,
return E_INVALIDARG;
}
nsCOMPtr<nsIDOMElement> element;
if (FAILED(GetDOMElement(getter_AddRefs(element))))
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
if (!element)
{
return E_UNEXPECTED;
}
@ -181,10 +169,10 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::removeAttribute(BSTR strAttributeName,
// Get the name from the BSTR
USES_CONVERSION;
nsString szName(OLE2W(strAttributeName));
nsAutoString name(OLE2W(strAttributeName));
// Remove the attribute
nsresult nr = element->RemoveAttribute(szName);
nsresult nr = element->RemoveAttribute(name);
BOOL bRemoved = (nr == NS_OK) ? TRUE : FALSE;
if (pfSuccess)
@ -246,17 +234,17 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_tagName(BSTR __RPC_FAR *p)
return E_INVALIDARG;
}
nsCOMPtr<nsIDOMElement> element;
if (FAILED(GetDOMElement(getter_AddRefs(element))))
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
if (!element)
{
return E_UNEXPECTED;
}
nsString szTagName;
element->GetTagName(szTagName);
nsAutoString tagName;
element->GetTagName(tagName);
USES_CONVERSION;
*p = SysAllocString(W2COLE(szTagName.get()));
*p = SysAllocString(W2COLE(tagName.get()));
return S_OK;
}
@ -268,9 +256,10 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_parentElement(IHTMLElement __RPC_F
}
*p = NULL;
if (m_pIDispParent)
if (mParent)
{
m_pIDispParent->QueryInterface(IID_IHTMLElement, (void **) p);
IDispatch *pDisp = reinterpret_cast<IDispatch *>(mParent);
pDisp->QueryInterface(IID_IHTMLElement, (void **) p);
}
return S_OK;
@ -458,13 +447,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_lang(BSTR __RPC_FAR *p)
HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetLeft(long __RPC_FAR *p)
{
nsCOMPtr<nsIDOMNode> domNode;
if (FAILED(GetDOMNode(getter_AddRefs(domNode))))
{
return E_UNEXPECTED;
}
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(domNode);
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
if (!nodeAsHTMLElement)
{
return E_NOINTERFACE;
@ -478,13 +461,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetLeft(long __RPC_FAR *p)
HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetTop(long __RPC_FAR *p)
{
nsCOMPtr<nsIDOMNode> domNode;
if (FAILED(GetDOMNode(getter_AddRefs(domNode))))
{
return E_UNEXPECTED;
}
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(domNode);
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
if (!nodeAsHTMLElement)
{
return E_NOINTERFACE;
@ -498,13 +475,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetTop(long __RPC_FAR *p)
HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetWidth(long __RPC_FAR *p)
{
nsCOMPtr<nsIDOMNode> domNode;
if (FAILED(GetDOMNode(getter_AddRefs(domNode))))
{
return E_UNEXPECTED;
}
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(domNode);
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
if (!nodeAsHTMLElement)
{
return E_NOINTERFACE;
@ -518,13 +489,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetWidth(long __RPC_FAR *p)
HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetHeight(long __RPC_FAR *p)
{
nsCOMPtr<nsIDOMNode> domNode;
if (FAILED(GetDOMNode(getter_AddRefs(domNode))))
{
return E_UNEXPECTED;
}
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(domNode);
nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
if (!nodeAsHTMLElement)
{
return E_NOINTERFACE;
@ -548,24 +513,33 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_innerHTML(BSTR v)
HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_innerHTML(BSTR __RPC_FAR *p)
{
nsCOMPtr<nsIDOMElement> element;
if (FAILED(GetDOMElement(getter_AddRefs(element))))
nsCOMPtr<nsIDOMNSHTMLElement> elementHTML = do_QueryInterface(mDOMNode);
if (!elementHTML)
{
return E_UNEXPECTED;
return E_UNEXPECTED;
}
nsCOMPtr<nsIDOMNSHTMLElement> elementHTML = do_QueryInterface(element);
nsAutoString szTagName;
elementHTML->GetInnerHTML(szTagName);
nsAutoString innerHTML;
elementHTML->GetInnerHTML(innerHTML);
USES_CONVERSION;
*p = SysAllocString(W2COLE(szTagName.get()));
*p = SysAllocString(W2COLE(innerHTML.get()));
return S_OK;
}
HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_innerText(BSTR v)
{
return E_NOTIMPL;
nsCOMPtr<nsIDOMNSHTMLElement> elementHTML = do_QueryInterface(mDOMNode);
if (!elementHTML)
{
return E_UNEXPECTED;
}
USES_CONVERSION;
nsAutoString innerHTML(OLE2W(v));
elementHTML->SetInnerHTML(innerHTML);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_innerText(BSTR __RPC_FAR *p)

Просмотреть файл

@ -42,11 +42,13 @@
#include "IEHtmlNode.h"
#include "IEHtmlElementCollection.h"
class CIEHtmlElement : public CIEHtmlNode,
public IDispatchImpl<IHTMLElement, &IID_IHTMLElement, &LIBID_MSHTML>
class CIEHtmlElement :
public CIEHtmlNode,
public IDispatchImpl<IHTMLElement, &IID_IHTMLElement, &LIBID_MSHTML>
{
public:
CIEHtmlElement();
protected:
virtual ~CIEHtmlElement();
@ -57,7 +59,6 @@ BEGIN_COM_MAP(CIEHtmlElement)
COM_INTERFACE_ENTRY_IID(IID_IHTMLElement, IHTMLElement)
END_COM_MAP()
virtual HRESULT GetIDispatch(IDispatch **pDispatch);
virtual HRESULT GetChildren(CIEHtmlElementCollectionInstance **ppCollection);
// Implementation of IHTMLElement

Просмотреть файл

@ -43,9 +43,12 @@
#include "IEHtmlElement.h"
#include "IEHtmlElementCollection.h"
#include "nsIDOMDocumentTraversal.h"
#include "nsIDOMTreeWalker.h"
#include "nsIDOMNodeFilter.h"
CIEHtmlElementCollection::CIEHtmlElementCollection()
{
m_pIDispParent = NULL;
mNodeList = NULL;
mNodeListCount = 0;
mNodeListCapacity = 0;
@ -71,14 +74,7 @@ CIEHtmlElementCollection::~CIEHtmlElementCollection()
}
}
HRESULT CIEHtmlElementCollection::SetParentNode(IDispatch *pIDispParent)
{
m_pIDispParent = pIDispParent;
return S_OK;
}
template <class nodeListType>
HRESULT PopulateFromList(CIEHtmlElementCollection *pCollection, nodeListType *pNodeList, BOOL bRecurseChildren)
HRESULT CIEHtmlElementCollection::PopulateFromDOMHTMLCollection(nsIDOMHTMLCollection *pNodeList)
{
if (pNodeList == nsnull)
{
@ -119,7 +115,7 @@ HRESULT PopulateFromList(CIEHtmlElementCollection *pCollection, nodeListType *pN
{
CIEHtmlElementInstance::CreateInstance(&pHtmlElement);
pHtmlElement->SetDOMNode(childNode);
pHtmlElement->SetParentNode(pCollection->m_pIDispParent);
pHtmlElement->SetParent(mParent);
}
else
{
@ -127,59 +123,84 @@ HRESULT PopulateFromList(CIEHtmlElementCollection *pCollection, nodeListType *pN
}
if (pHtmlElement)
{
pCollection->AddNode(pHtmlElement);
}
if (bRecurseChildren)
{
// Test if the node has children and recursively add them too
nsCOMPtr<nsIDOMNodeList> childNodeList;
childNode->GetChildNodes(getter_AddRefs(childNodeList));
PRUint32 childListLength = 0;
if (childNodeList)
{
childNodeList->GetLength(&childListLength);
}
if (childListLength > 0)
{
PopulateFromList<nsIDOMNodeList>(pCollection, childNodeList, bRecurseChildren);
}
AddNode(pHtmlElement);
}
}
return S_OK;
}
HRESULT CIEHtmlElementCollection::PopulateFromDOMNodeList(nsIDOMNodeList *pNodeList, BOOL bRecurseChildren)
HRESULT CIEHtmlElementCollection::PopulateFromDOMNode(nsIDOMNode *aDOMNode, BOOL bRecurseChildren)
{
return PopulateFromList<nsIDOMNodeList>(this, pNodeList, bRecurseChildren);
}
HRESULT CIEHtmlElementCollection::PopulateFromDOMHTMLCollection(nsIDOMHTMLCollection *pNodeList, BOOL bRecurseChildren)
{
return PopulateFromList<nsIDOMHTMLCollection>(this, pNodeList, bRecurseChildren);
}
HRESULT CIEHtmlElementCollection::PopulateFromDOMNode(nsIDOMNode *pIDOMNode, BOOL bRecurseChildren)
{
if (pIDOMNode == nsnull)
if (aDOMNode == nsnull)
{
NG_ASSERT(0);
return E_INVALIDARG;
}
// Get elements from the DOM node
nsCOMPtr<nsIDOMNodeList> nodeList;
pIDOMNode->GetChildNodes(getter_AddRefs(nodeList));
if (!nodeList)
PRBool hasChildNodes = PR_FALSE;
aDOMNode->HasChildNodes(&hasChildNodes);
if (hasChildNodes)
{
return S_OK;
}
if (bRecurseChildren)
{
nsresult rv;
return PopulateFromDOMNodeList(nodeList, bRecurseChildren);
// Search through parent nodes, looking for the DOM document
nsCOMPtr<nsIDOMNode> docAsNode = aDOMNode;
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDOMNode);
while (!doc) {
docAsNode->GetParentNode(getter_AddRefs(docAsNode));
if (!docAsNode)
{
return E_FAIL;
}
doc = do_QueryInterface(docAsNode);
}
// Walk the DOM
nsCOMPtr<nsIDOMDocumentTraversal> trav = do_QueryInterface(doc, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMTreeWalker> walker;
rv = trav->CreateTreeWalker(docAsNode,
nsIDOMNodeFilter::SHOW_ELEMENT,
nsnull, PR_TRUE, getter_AddRefs(walker));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
// We're not interested in the document node, so we always start
// with the next one, walking through them all to make the collection
nsCOMPtr<nsIDOMNode> currentNode;
walker->NextNode(getter_AddRefs(currentNode));
while (currentNode)
{
// Create an equivalent IE element
CIEHtmlNode *pHtmlNode = NULL;
CIEHtmlElementInstance *pHtmlElement = NULL;
CIEHtmlElementInstance::FindFromDOMNode(currentNode, &pHtmlNode);
if (!pHtmlNode)
{
CIEHtmlElementInstance::CreateInstance(&pHtmlElement);
pHtmlElement->SetDOMNode(currentNode);
pHtmlElement->SetParent(mParent);
}
else
{
pHtmlElement = (CIEHtmlElementInstance *) pHtmlNode;
}
if (pHtmlElement)
{
AddNode(pHtmlElement);
}
walker->NextNode(getter_AddRefs(currentNode));
}
}
else
{
nsCOMPtr<nsIDOMNodeList> nodeList;
aDOMNode->GetChildNodes(getter_AddRefs(nodeList));
mDOMNodeList = nodeList;
}
}
return S_OK;
}
@ -192,9 +213,7 @@ HRESULT CIEHtmlElementCollection::CreateFromDOMHTMLCollection(CIEHtmlNode *pPare
}
// Get the DOM node from the parent node
nsCOMPtr<nsIDOMNode> domNode;
pParentNode->GetDOMNode(getter_AddRefs(domNode));
if (!domNode)
if (!pParentNode->mDOMNode)
{
NG_ASSERT(0);
return E_INVALIDARG;
@ -212,50 +231,8 @@ HRESULT CIEHtmlElementCollection::CreateFromDOMHTMLCollection(CIEHtmlNode *pPare
}
// Initialise and populate the collection
CIPtr(IDispatch) cpDispNode;
pParentNode->GetIDispatch(&cpDispNode);
pCollection->SetParentNode(cpDispNode);
pCollection->PopulateFromDOMHTMLCollection(pNodeList, FALSE);
*pInstance = pCollection;
return S_OK;
}
HRESULT CIEHtmlElementCollection::CreateFromDOMNodeList(CIEHtmlNode *pParentNode, nsIDOMNodeList *pNodeList, CIEHtmlElementCollection **pInstance)
{
if (pInstance == NULL || pParentNode == NULL)
{
NG_ASSERT(0);
return E_INVALIDARG;
}
// Get the DOM node from the parent node
nsCOMPtr<nsIDOMNode> domNode;
pParentNode->GetDOMNode(getter_AddRefs(domNode));
if (!domNode)
{
NG_ASSERT(0);
return E_INVALIDARG;
}
*pInstance = NULL;
// Create a collection object
CIEHtmlElementCollectionInstance *pCollection = NULL;
CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
if (pCollection == NULL)
{
NG_ASSERT(0);
return E_OUTOFMEMORY;
}
// Initialise and populate the collection
CIPtr(IDispatch) cpDispNode;
pParentNode->GetIDispatch(&cpDispNode);
pCollection->SetParentNode(cpDispNode);
pCollection->PopulateFromDOMNodeList(pNodeList, FALSE);
pCollection->SetParent(pParentNode);
pCollection->PopulateFromDOMHTMLCollection(pNodeList);
*pInstance = pCollection;
@ -271,9 +248,7 @@ HRESULT CIEHtmlElementCollection::CreateFromParentNode(CIEHtmlNode *pParentNode,
}
// Get the DOM node from the parent node
nsCOMPtr<nsIDOMNode> domNode;
pParentNode->GetDOMNode(getter_AddRefs(domNode));
if (!domNode)
if (!pParentNode->mDOMNode)
{
NG_ASSERT(0);
return E_INVALIDARG;
@ -291,10 +266,8 @@ HRESULT CIEHtmlElementCollection::CreateFromParentNode(CIEHtmlNode *pParentNode,
}
// Initialise and populate the collection
CIPtr(IDispatch) cpDispNode;
pParentNode->GetIDispatch(&cpDispNode);
pCollection->SetParentNode(cpDispNode);
pCollection->PopulateFromDOMNode(domNode, bRecurseChildren);
pCollection->SetParent(pParentNode);
pCollection->PopulateFromDOMNode(pParentNode->mDOMNode, bRecurseChildren);
*pInstance = pCollection;
@ -310,7 +283,7 @@ HRESULT CIEHtmlElementCollection::AddNode(IDispatch *pNode)
return E_INVALIDARG;
}
const PRUint32 c_NodeListResizeBy = 10;
const PRUint32 c_NodeListResizeBy = 100;
if (mNodeList == NULL)
{
@ -367,7 +340,38 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get_length(long __RPC_FAR *p
}
// Return the size of the collection
*p = mNodeListCount;
if (mDOMNodeList)
{
// Count the number of elements in the list
PRUint32 elementCount = 0;
PRUint32 length = 0;
mDOMNodeList->GetLength(&length);
for (PRUint32 i = 0; i < length; i++)
{
// Get the next item from the list
nsCOMPtr<nsIDOMNode> childNode;
mDOMNodeList->Item(i, getter_AddRefs(childNode));
if (!childNode)
{
// Empty node (unexpected, but try and carry on anyway)
NG_ASSERT(0);
continue;
}
// Only count elements
PRUint16 nodeType;
childNode->GetNodeType(&nodeType);
if (nodeType == nsIDOMNode::ELEMENT_NODE)
{
elementCount++;
}
}
*p = elementCount;
}
else
{
*p = mNodeListCount;
}
return S_OK;
}
@ -375,6 +379,8 @@ typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARI
HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get__newEnum(IUnknown __RPC_FAR *__RPC_FAR *p)
{
NG_TRACE_METHOD(CIEHtmlElementCollection::get__newEnum);
if (p == NULL)
{
return E_INVALIDARG;
@ -391,8 +397,9 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get__newEnum(IUnknown __RPC_
return E_OUTOFMEMORY;
}
int nObject;
int nObjects = mNodeListCount;
int nObject = 0;
long nObjects = 0;
get_length(&nObjects);
// Create an array of VARIANTs
VARIANT *avObjects = new VARIANT[nObjects];
@ -402,15 +409,64 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get__newEnum(IUnknown __RPC_
return E_OUTOFMEMORY;
}
// Copy the contents of the collection to the array
for (nObject = 0; nObject < nObjects; nObject++)
if (mDOMNodeList)
{
VARIANT *pVariant = &avObjects[nObject];
IUnknown *pUnkObject = mNodeList[nObject];
VariantInit(pVariant);
pVariant->vt = VT_UNKNOWN;
pVariant->punkVal = pUnkObject;
pUnkObject->AddRef();
// Fill the variant array with elements from the DOM node list
PRUint32 length = 0;
mDOMNodeList->GetLength(&length);
for (PRUint32 i = 0; i < length; i++)
{
// Get the next item from the list
nsCOMPtr<nsIDOMNode> childNode;
mDOMNodeList->Item(i, getter_AddRefs(childNode));
if (!childNode)
{
// Empty node (unexpected, but try and carry on anyway)
NG_ASSERT(0);
continue;
}
// Skip nodes representing, text, attributes etc.
PRUint16 nodeType;
childNode->GetNodeType(&nodeType);
if (nodeType != nsIDOMNode::ELEMENT_NODE)
{
continue;
}
// Store the element in the array
CIEHtmlNode *pHtmlNode = NULL;
CIEHtmlElementInstance *pHtmlElement = NULL;
CIEHtmlElementInstance::FindFromDOMNode(childNode, &pHtmlNode);
if (!pHtmlNode)
{
CIEHtmlElementInstance::CreateInstance(&pHtmlElement);
pHtmlElement->SetDOMNode(childNode);
pHtmlElement->SetParent(mParent);
}
else
{
pHtmlElement = (CIEHtmlElementInstance *) pHtmlNode;
}
VARIANT *pVariant = &avObjects[nObject++];
VariantInit(pVariant);
pVariant->vt = VT_UNKNOWN;
pHtmlElement->QueryInterface(IID_IUnknown, (void **) &pVariant->punkVal);
}
}
else
{
// Copy the contents of the collection to the array
for (nObject = 0; nObject < nObjects; nObject++)
{
VARIANT *pVariant = &avObjects[nObject];
IUnknown *pUnkObject = mNodeList[nObject];
VariantInit(pVariant);
pVariant->vt = VT_UNKNOWN;
pVariant->punkVal = pUnkObject;
pUnkObject->AddRef();
}
}
// Copy the variants to the enumeration object
@ -430,6 +486,8 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get__newEnum(IUnknown __RPC_
HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::item(VARIANT name, VARIANT index, IDispatch __RPC_FAR *__RPC_FAR *pdisp)
{
NG_TRACE_METHOD(CIEHtmlElementCollection::item);
if (pdisp == NULL)
{
return E_INVALIDARG;
@ -444,22 +502,81 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::item(VARIANT name, VARIANT i
if (SUCCEEDED(vIndex.ChangeType(VT_I4, &name)) ||
SUCCEEDED(vIndex.ChangeType(VT_I4, &index)))
{
// Test for stupid values
int nIndex = vIndex.lVal;
if (nIndex < 0 || nIndex >= mNodeListCount)
if (nIndex < 0)
{
return E_INVALIDARG;
}
*pdisp = NULL;
IDispatch *pNode = mNodeList[nIndex];
if (pNode == NULL)
if (mDOMNodeList)
{
NG_ASSERT(0);
return E_UNEXPECTED;
// Search for the Nth element in the list
PRUint32 elementCount = 0;
PRUint32 length = 0;
mDOMNodeList->GetLength(&length);
for (PRUint32 i = 0; i < length; i++)
{
// Get the next item from the list
nsCOMPtr<nsIDOMNode> childNode;
mDOMNodeList->Item(i, getter_AddRefs(childNode));
if (!childNode)
{
// Empty node (unexpected, but try and carry on anyway)
NG_ASSERT(0);
continue;
}
// Skip nodes representing, text, attributes etc.
PRUint16 nodeType;
childNode->GetNodeType(&nodeType);
if (nodeType != nsIDOMNode::ELEMENT_NODE)
{
continue;
}
// Have we found the element we need?
if (elementCount == nIndex)
{
// Return the element
CIEHtmlNode *pHtmlNode = NULL;
CIEHtmlElementInstance *pHtmlElement = NULL;
CIEHtmlElementInstance::FindFromDOMNode(childNode, &pHtmlNode);
if (!pHtmlNode)
{
CIEHtmlElementInstance::CreateInstance(&pHtmlElement);
pHtmlElement->SetDOMNode(childNode);
pHtmlElement->SetParent(mParent);
}
else
{
pHtmlElement = (CIEHtmlElementInstance *) pHtmlNode;
}
pHtmlElement->QueryInterface(IID_IDispatch, (void **) pdisp);
return S_OK;
}
elementCount++;
}
// Index must have been out of range
return E_INVALIDARG;
}
else
{
// Test for stupid values
if (nIndex >= mNodeListCount)
{
return E_INVALIDARG;
}
*pdisp = NULL;
IDispatch *pNode = mNodeList[nIndex];
if (pNode == NULL)
{
NG_ASSERT(0);
return E_UNEXPECTED;
}
pNode->QueryInterface(IID_IDispatch, (void **) pdisp);
}
pNode->QueryInterface(IID_IDispatch, (void **) pdisp);
return S_OK;
}
else if (SUCCEEDED(vIndex.ChangeType(VT_BSTR, &index)))

Просмотреть файл

@ -46,13 +46,17 @@
class CIEHtmlElement;
class CIEHtmlElementCollection : public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IHTMLElementCollection, &IID_IHTMLElementCollection, &LIBID_MSHTML>
class CIEHtmlElementCollection :
public CIEHtmlNode,
public IDispatchImpl<IHTMLElementCollection, &IID_IHTMLElementCollection, &LIBID_MSHTML>
{
private:
IDispatch **mNodeList;
PRUint32 mNodeListCount;
PRUint32 mNodeListCapacity;
// Hold a DOM node list
nsCOMPtr<nsIDOMNodeList> mDOMNodeList;
// Or hold a static collection
IDispatch **mNodeList;
PRUint32 mNodeListCount;
PRUint32 mNodeListCapacity;
public:
CIEHtmlElementCollection();
@ -61,20 +65,10 @@ protected:
virtual ~CIEHtmlElementCollection();
public:
// Pointer to parent node/document
IDispatch *m_pIDispParent;
// Adds a node to the collection
virtual HRESULT AddNode(IDispatch *pNode);
// Sets the parent node of this collection
virtual HRESULT SetParentNode(IDispatch *pIDispParent);
// Populates the collection from a DOM HTML collection
virtual HRESULT PopulateFromDOMHTMLCollection(nsIDOMHTMLCollection *pNodeList, BOOL bRecurseChildren);
// Populates the collection from a DOM node list
virtual HRESULT PopulateFromDOMNodeList(nsIDOMNodeList *pNodeList, BOOL bRecurseChildren);
virtual HRESULT PopulateFromDOMHTMLCollection(nsIDOMHTMLCollection *pNodeList);
// Populates the collection with items from the DOM node
virtual HRESULT PopulateFromDOMNode(nsIDOMNode *pIDOMNode, BOOL bRecurseChildren);
@ -82,9 +76,6 @@ public:
// Helper method creates a collection from a parent node
static HRESULT CreateFromParentNode(CIEHtmlNode *pParentNode, BOOL bRecurseChildren, CIEHtmlElementCollection **pInstance);
// Helper method creates a collection from the specified node list
static HRESULT CreateFromDOMNodeList(CIEHtmlNode *pParentNode, nsIDOMNodeList *pNodeList, CIEHtmlElementCollection **pInstance);
// Helper method creates a collection from the specified HTML collection
static HRESULT CreateFromDOMHTMLCollection(CIEHtmlNode *pParentNode, nsIDOMHTMLCollection *pNodeList, CIEHtmlElementCollection **pInstance);

Просмотреть файл

@ -52,16 +52,15 @@ PRIntn PR_CALLBACK HashComparator(const void *v1, const void *v2)
{
if (v1 == v2)
{
return 0;
return 1;
}
return (v1 > v2) ? 1 : 0;
return 0;
}
CIEHtmlNode::CIEHtmlNode()
CIEHtmlNode::CIEHtmlNode() :
mParent(NULL)
{
m_pIDOMNode = nsnull;
m_pIDispParent = NULL;
}
CIEHtmlNode::~CIEHtmlNode()
@ -70,9 +69,9 @@ CIEHtmlNode::~CIEHtmlNode()
}
HRESULT CIEHtmlNode::SetParentNode(IDispatch *pIDispParent)
HRESULT CIEHtmlNode::SetParent(CIEHtmlNode *pParent)
{
m_pIDispParent = pIDispParent;
mParent = pParent;
return S_OK;
}
@ -89,96 +88,37 @@ HRESULT CIEHtmlNode::FindFromDOMNode(nsIDOMNode *pIDOMNode, CIEHtmlNode **pHtmlN
return E_FAIL;
}
nsISupports *pISupports = nsnull;
pIDOMNode->QueryInterface(NS_GET_IID(nsISupports), (void **) &pISupports);
NG_ASSERT(pISupports);
*pHtmlNode = (CIEHtmlNode *) PL_HashTableLookup(g_NodeLookupTable, pISupports);
NS_RELEASE(pISupports);
nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(pIDOMNode);
*pHtmlNode = (CIEHtmlNode *) PL_HashTableLookup(g_NodeLookupTable, nodeAsSupports);
return S_OK;
}
HRESULT CIEHtmlNode::SetDOMNode(nsIDOMNode *pIDOMNode)
{
if (pIDOMNode)
{
NS_IF_RELEASE(m_pIDOMNode);
m_pIDOMNode = pIDOMNode;
NS_ADDREF(m_pIDOMNode);
if (g_NodeLookupTable == NULL)
{
g_NodeLookupTable = PL_NewHashTable(123, HashFunction, HashComparator, NULL, NULL, NULL);
}
nsISupports *pISupports = nsnull;
m_pIDOMNode->QueryInterface(NS_GET_IID(nsISupports), (void **) &pISupports);
PL_HashTableAdd(g_NodeLookupTable, m_pIDOMNode, this);
NS_RELEASE(pISupports);
mDOMNode = pIDOMNode;
nsCOMPtr<nsISupports> nodeAsSupports= do_QueryInterface(mDOMNode);
PL_HashTableAdd(g_NodeLookupTable, nodeAsSupports, this);
}
else if (m_pIDOMNode)
else if (mDOMNode)
{
// Remove the entry from the hashtable
nsISupports *pISupports = nsnull;
m_pIDOMNode->QueryInterface(NS_GET_IID(nsISupports), (void **) &pISupports);
PL_HashTableRemove(g_NodeLookupTable, pISupports);
NS_RELEASE(pISupports);
nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(mDOMNode);
PL_HashTableRemove(g_NodeLookupTable, nodeAsSupports);
mDOMNode = nsnull;
if (g_NodeLookupTable->nentries == 0)
{
PL_HashTableDestroy(g_NodeLookupTable);
g_NodeLookupTable = NULL;
}
NS_RELEASE(m_pIDOMNode);
}
return S_OK;
}
HRESULT CIEHtmlNode::GetDOMNode(nsIDOMNode **pIDOMNode)
{
if (pIDOMNode == NULL)
{
return E_INVALIDARG;
}
*pIDOMNode = nsnull;
if (m_pIDOMNode)
{
NS_ADDREF(m_pIDOMNode);
*pIDOMNode = m_pIDOMNode;
}
return S_OK;
}
HRESULT CIEHtmlNode::GetDOMElement(nsIDOMElement **pIDOMElement)
{
if (pIDOMElement == NULL)
{
return E_INVALIDARG;
}
if (m_pIDOMNode == nsnull)
{
return E_NOINTERFACE;
}
*pIDOMElement = nsnull;
m_pIDOMNode->QueryInterface(NS_GET_IID(nsIDOMElement), (void **) pIDOMElement);
return (*pIDOMElement) ? S_OK : E_NOINTERFACE;
}
HRESULT CIEHtmlNode::GetIDispatch(IDispatch **pDispatch)
{
if (pDispatch == NULL)
{
return E_INVALIDARG;
}
*pDispatch = NULL;
return E_NOINTERFACE;
}

Просмотреть файл

@ -39,25 +39,21 @@
#ifndef IEHTMLNODE_H
#define IEHTMLNODE_H
class CIEHtmlNode : public CComObjectRootEx<CComSingleThreadModel>
class CIEHtmlNode :
public CComObjectRootEx<CComMultiThreadModel>
{
protected:
nsIDOMNode *m_pIDOMNode;
IDispatch *m_pIDispParent;
public:
CIEHtmlNode();
protected:
virtual ~CIEHtmlNode();
public:
CIEHtmlNode *mParent;
nsCOMPtr<nsIDOMNode> mDOMNode;
static HRESULT FindFromDOMNode(nsIDOMNode *pIDOMNode, CIEHtmlNode **pHtmlNode);
virtual HRESULT SetParent(CIEHtmlNode *mParent);
virtual HRESULT SetDOMNode(nsIDOMNode *pIDOMNode);
virtual HRESULT GetDOMNode(nsIDOMNode **pIDOMNode);
virtual HRESULT GetDOMElement(nsIDOMElement **pIDOMElement);
virtual HRESULT SetParentNode(IDispatch *pIDispParent);
virtual HRESULT GetIDispatch(IDispatch **pDispatch);
};
typedef CComObject<CIEHtmlNode> CIEHtmlNodeInstance;

Просмотреть файл

@ -22,7 +22,6 @@
* Contributor(s):
* Adam Lock <adamlock@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),