diff --git a/webshell/embed/ActiveX/IEHtmlDocument.cpp b/webshell/embed/ActiveX/IEHtmlDocument.cpp index d118f293addd..61466e3be16c 100644 --- a/webshell/embed/ActiveX/IEHtmlDocument.cpp +++ b/webshell/embed/ActiveX/IEHtmlDocument.cpp @@ -25,10 +25,22 @@ CIEHtmlDocument::CIEHtmlDocument() { } + CIEHtmlDocument::~CIEHtmlDocument() { } + +HRESULT CIEHtmlDocument::GetIDispatch(IDispatch **pDispatch) +{ + if (pDispatch == NULL) + { + return E_INVALIDARG; + } + return QueryInterface(IID_IDispatch, (void **) pDispatch); +} + + /////////////////////////////////////////////////////////////////////////////// // IHTMLDocument methods @@ -49,6 +61,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlDocument::get_all(IHTMLElementCollection __RPC_ *p = NULL; + // TODO get all elements CIEHtmlElementCollectionInstance *pCollection = NULL; CIEHtmlElementCollection::CreateFromParentNode(this, (CIEHtmlElementCollection **) &pCollection); if (pCollection) diff --git a/webshell/embed/ActiveX/IEHtmlDocument.h b/webshell/embed/ActiveX/IEHtmlDocument.h index 6cb069b06d6d..729b3d15d702 100644 --- a/webshell/embed/ActiveX/IEHtmlDocument.h +++ b/webshell/embed/ActiveX/IEHtmlDocument.h @@ -36,6 +36,8 @@ BEGIN_COM_MAP(CIEHtmlDocument) COM_INTERFACE_ENTRY_IID(IID_IHTMLDocument2, IHTMLDocument2) END_COM_MAP() + virtual HRESULT GetIDispatch(IDispatch **pDispatch); + // IHTMLDocument methods virtual HRESULT STDMETHODCALLTYPE get_Script(IDispatch __RPC_FAR *__RPC_FAR *p); diff --git a/webshell/embed/ActiveX/IEHtmlElement.cpp b/webshell/embed/ActiveX/IEHtmlElement.cpp index 5525a3fd0df7..87e370969f0b 100644 --- a/webshell/embed/ActiveX/IEHtmlElement.cpp +++ b/webshell/embed/ActiveX/IEHtmlElement.cpp @@ -32,22 +32,126 @@ CIEHtmlElement::~CIEHtmlElement() { } + +HRESULT CIEHtmlElement::GetIDispatch(IDispatch **pDispatch) +{ + if (pDispatch == NULL) + { + return E_INVALIDARG; + } + return QueryInterface(IID_IDispatch, (void **) pDispatch); +} + /////////////////////////////////////////////////////////////////////////////// // IHTMLElement implementation HRESULT STDMETHODCALLTYPE CIEHtmlElement::setAttribute(BSTR strAttributeName, VARIANT AttributeValue, LONG lFlags) { - return E_NOTIMPL; + if (strAttributeName == NULL) + { + return E_INVALIDARG; + } + + // Get the name from the BSTR + USES_CONVERSION; + nsString szName = OLE2W(strAttributeName); + + // Get the value from the variant + CComVariant vValue; + if (FAILED(vValue.ChangeType(VT_BSTR, &AttributeValue))) + { + return E_INVALIDARG; + } + nsString szValue = OLE2W(vValue.bstrVal); + + nsIDOMElement *pIDOMElement = nsnull; + if (FAILED(GetDOMElement(&pIDOMElement))) + { + return E_UNEXPECTED; + } + + // Set the attribute + pIDOMElement->SetAttribute(szName, szValue); + pIDOMElement->Release(); + + return S_OK; } HRESULT STDMETHODCALLTYPE CIEHtmlElement::getAttribute(BSTR strAttributeName, LONG lFlags, VARIANT __RPC_FAR *AttributeValue) { - return E_NOTIMPL; + if (strAttributeName == NULL) + { + return E_INVALIDARG; + } + if (AttributeValue == NULL) + { + return E_INVALIDARG; + } + VariantInit(AttributeValue); + + // Get the name from the BSTR + USES_CONVERSION; + nsString szName = OLE2W(strAttributeName); + + nsIDOMElement *pIDOMElement = nsnull; + if (FAILED(GetDOMElement(&pIDOMElement))) + { + return E_UNEXPECTED; + } + + BOOL bCaseSensitive = (lFlags == VARIANT_TRUE) ? TRUE : FALSE; + + nsString szValue; + + // Get the attribute + nsresult nr = pIDOMElement->GetAttribute(szName, szValue); + pIDOMElement->Release(); + + if (nr == NS_OK) + { + USES_CONVERSION; + AttributeValue->vt = VT_BSTR; + AttributeValue->bstrVal = SysAllocString(W2COLE((const PRUnichar *) szValue)); + return S_OK; + } + else + { + return S_FALSE; + } + + return S_OK; } HRESULT STDMETHODCALLTYPE CIEHtmlElement::removeAttribute(BSTR strAttributeName, LONG lFlags, VARIANT_BOOL __RPC_FAR *pfSuccess) { - return E_NOTIMPL; + if (strAttributeName == NULL) + { + return E_INVALIDARG; + } + + nsIDOMElement *pIDOMElement = nsnull; + if (FAILED(GetDOMElement(&pIDOMElement))) + { + return E_UNEXPECTED; + } + + BOOL bCaseSensitive = (lFlags == VARIANT_TRUE) ? TRUE : FALSE; + + // Get the name from the BSTR + USES_CONVERSION; + nsString szName = OLE2W(strAttributeName); + + // Remove the attribute + nsresult nr = pIDOMElement->RemoveAttribute(szName); + BOOL bRemoved = (nr == NS_OK) ? TRUE : FALSE; + pIDOMElement->Release(); + + if (pfSuccess) + { + *pfSuccess = (bRemoved) ? VARIANT_TRUE : VARIANT_FALSE; + } + + return S_OK; } HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_className(BSTR v) @@ -61,8 +165,14 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_className(BSTR __RPC_FAR *p) { return E_INVALIDARG; } - // TODO - *p = SysAllocString(OLESTR("")); + + VARIANT vValue; + VariantInit(&vValue); + BSTR bstrName = SysAllocString(OLESTR("class")); + getAttribute(bstrName, FALSE, &vValue); + SysFreeString(bstrName); + + *p = vValue.bstrVal; return S_OK; } @@ -77,8 +187,14 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_id(BSTR __RPC_FAR *p) { return E_INVALIDARG; } - // TODO - *p = SysAllocString(OLESTR("")); + + VARIANT vValue; + VariantInit(&vValue); + BSTR bstrName = SysAllocString(OLESTR("id")); + getAttribute(bstrName, FALSE, &vValue); + SysFreeString(bstrName); + + *p = vValue.bstrVal; return S_OK; } @@ -89,11 +205,18 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_tagName(BSTR __RPC_FAR *p) return E_INVALIDARG; } - nsString sNodeName; - m_pIDOMNode->GetNodeName(sNodeName); + nsIDOMElement *pIDOMElement = nsnull; + if (FAILED(GetDOMElement(&pIDOMElement))) + { + return E_UNEXPECTED; + } + + nsString szTagName; + pIDOMElement->GetTagName(szTagName); + pIDOMElement->Release(); USES_CONVERSION; - *p = SysAllocString(W2COLE((const PRUnichar *) sNodeName)); + *p = SysAllocString(W2COLE((const PRUnichar *) szTagName)); return S_OK; } @@ -105,9 +228,9 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_parentElement(IHTMLElement __RPC_F } *p = NULL; - if (m_pParent) + if (m_pIDispParent) { -// m_pParent->QueryInterface(IID_IHTMLElement, (void **) p); + m_pIDispParent->QueryInterface(IID_IHTMLElement, (void **) p); } return S_OK; @@ -503,6 +626,7 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_children(IDispatch __RPC_FAR *__RP *p = NULL; + // Create a collection representing the children of this node CIEHtmlElementCollectionInstance *pCollection = NULL; CIEHtmlElementCollection::CreateFromParentNode(this, (CIEHtmlElementCollection **) &pCollection); if (pCollection) diff --git a/webshell/embed/ActiveX/IEHtmlElement.h b/webshell/embed/ActiveX/IEHtmlElement.h index fdb455decf05..c93d1350956b 100644 --- a/webshell/embed/ActiveX/IEHtmlElement.h +++ b/webshell/embed/ActiveX/IEHtmlElement.h @@ -35,6 +35,8 @@ BEGIN_COM_MAP(CIEHtmlElement) COM_INTERFACE_ENTRY_IID(IID_IHTMLElement, IHTMLElement) END_COM_MAP() + virtual HRESULT GetIDispatch(IDispatch **pDispatch); + // Implementation of IHTMLElement virtual HRESULT STDMETHODCALLTYPE setAttribute(BSTR strAttributeName, VARIANT AttributeValue, LONG lFlags); virtual HRESULT STDMETHODCALLTYPE getAttribute(BSTR strAttributeName, LONG lFlags, VARIANT __RPC_FAR *AttributeValue); diff --git a/webshell/embed/ActiveX/IEHtmlElementCollection.cpp b/webshell/embed/ActiveX/IEHtmlElementCollection.cpp index b348e4471f2d..1e711d0c1f4e 100644 --- a/webshell/embed/ActiveX/IEHtmlElementCollection.cpp +++ b/webshell/embed/ActiveX/IEHtmlElementCollection.cpp @@ -21,16 +21,16 @@ CIEHtmlElementCollection::CIEHtmlElementCollection() { - m_pParent = NULL; + m_pIDispParent = NULL; } CIEHtmlElementCollection::~CIEHtmlElementCollection() { } -HRESULT CIEHtmlElementCollection::SetParentNode(CIEHtmlNode *pParent) +HRESULT CIEHtmlElementCollection::SetParentNode(IDispatch *pIDispParent) { - m_pParent = pParent; + m_pIDispParent = pIDispParent; return S_OK; } @@ -58,7 +58,9 @@ HRESULT CIEHtmlElementCollection::CreateFromParentNode(CIEHtmlNode *pParentNode, CIEHtmlElementCollectionInstance *pCollection = NULL; CIEHtmlElementCollectionInstance::CreateInstance(&pCollection); - pCollection->SetParentNode(pParentNode); + CIPtr(IDispatch) cpDispNode; + pParentNode->GetIDispatch(&cpDispNode); + pCollection->SetParentNode(cpDispNode); // Get elements nsIDOMNodeList *pIDOMNodeList = nsnull; @@ -78,7 +80,7 @@ HRESULT CIEHtmlElementCollection::CreateFromParentNode(CIEHtmlNode *pParentNode, if (pElement) { pElement->SetDOMNode(pChildNode); - pElement->SetParentNode(pCollection->m_pParent); + pElement->SetParentNode(pCollection->m_pIDispParent); pCollection->AddNode(pElement); } @@ -120,14 +122,15 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::toString(BSTR __RPC_FAR *Str { return E_INVALIDARG; } - *String = SysAllocString(OLESTR("Element collection")); + *String = SysAllocString(OLESTR("ElementCollection")); return S_OK; } HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::put_length(long v) { - return E_NOTIMPL; + // What is the point of this method? + return S_OK; } @@ -137,6 +140,8 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get_length(long __RPC_FAR *p { return E_INVALIDARG; } + + // Return the size of the collection *p = m_cNodeList.size(); return S_OK; } @@ -144,42 +149,70 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get_length(long __RPC_FAR *p HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get__newEnum(IUnknown __RPC_FAR *__RPC_FAR *p) { + if (p == NULL) + { + return E_INVALIDARG; + } + *p = NULL; + // TODO Create a new IEnumVARIANT containing each member of the collection return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::item(VARIANT name, VARIANT index, IDispatch __RPC_FAR *__RPC_FAR *pdisp) { - CComVariant vIndex; - if (FAILED(vIndex.ChangeType(VT_I4, &index))) + if (pdisp == NULL) { return E_INVALIDARG; } - - int nIndex = vIndex.lVal; - if (nIndex < 0 || nIndex >= m_cNodeList.size()) - { - return E_INVALIDARG; - } - *pdisp = NULL; - IDispatch *pNode = m_cNodeList[nIndex]; - if (pNode == NULL) + CComVariant vIndex; + if (SUCCEEDED(vIndex.ChangeType(VT_I4, &index))) { - NG_ASSERT(0); - return E_UNEXPECTED; + // Test for stupid values + int nIndex = vIndex.lVal; + if (nIndex < 0 || nIndex >= m_cNodeList.size()) + { + return E_INVALIDARG; + } + + *pdisp = NULL; + IDispatch *pNode = m_cNodeList[nIndex]; + if (pNode == NULL) + { + NG_ASSERT(0); + return E_UNEXPECTED; + } + + pNode->QueryInterface(IID_IDispatch, (void **) pdisp); + return S_OK; } + else if (SUCCEEDED(vIndex.ChangeType(VT_BSTR, &index))) + { + // If this parameter contains a string, the method returns + // a collection of objects, where the value of the name or + // id property for each object is equal to the string. - pNode->QueryInterface(IID_IDispatch, (void **) pdisp); - - return S_OK; + // TODO all of the above! + return E_NOTIMPL; + } + else + { + return E_INVALIDARG; + } } HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::tags(VARIANT tagName, IDispatch __RPC_FAR *__RPC_FAR *pdisp) { + if (pdisp == NULL) + { + return E_INVALIDARG; + } *pdisp = NULL; + // TODO + // iterate through collection looking for elements with matching tags return E_NOTIMPL; } diff --git a/webshell/embed/ActiveX/IEHtmlElementCollection.h b/webshell/embed/ActiveX/IEHtmlElementCollection.h index aeb9c2fd7222..e1205b81e439 100644 --- a/webshell/embed/ActiveX/IEHtmlElementCollection.h +++ b/webshell/embed/ActiveX/IEHtmlElementCollection.h @@ -32,14 +32,15 @@ public: protected: virtual ~CIEHtmlElementCollection(); - CIEHtmlNode *m_pParent; + // Pointer to parent node/document + IDispatch *m_pIDispParent; public: // Adds a node to the collection virtual HRESULT AddNode(IDispatch *pNode); // Sets the parent node of this collection - virtual HRESULT SetParentNode(CIEHtmlNode *pParent); + virtual HRESULT SetParentNode(IDispatch *pIDispParent); // Helper method creates a collection from a parent node static HRESULT CreateFromParentNode(CIEHtmlNode *pParentNode, CIEHtmlElementCollection **pInstance); diff --git a/webshell/embed/ActiveX/IEHtmlNode.cpp b/webshell/embed/ActiveX/IEHtmlNode.cpp index 71f27b7501af..e0e6873fe3d4 100644 --- a/webshell/embed/ActiveX/IEHtmlNode.cpp +++ b/webshell/embed/ActiveX/IEHtmlNode.cpp @@ -19,11 +19,12 @@ #include "IEHtmlNode.h" static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); +static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); CIEHtmlNode::CIEHtmlNode() { m_pIDOMNode = nsnull; - m_pParent = NULL; + m_pIDispParent = NULL; } CIEHtmlNode::~CIEHtmlNode() @@ -31,9 +32,9 @@ CIEHtmlNode::~CIEHtmlNode() SetDOMNode(nsnull); } -HRESULT CIEHtmlNode::SetParentNode(CIEHtmlNode *pParent) +HRESULT CIEHtmlNode::SetParentNode(IDispatch *pIDispParent) { - m_pParent = pParent; + m_pIDispParent = pIDispParent; return S_OK; } @@ -70,3 +71,31 @@ HRESULT CIEHtmlNode::GetDOMNode(nsIDOMNode **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(kIDOMElementIID, (void **) pIDOMElement); + return (*pIDOMElement) ? S_OK : E_NOINTERFACE; +} + +HRESULT CIEHtmlNode::GetIDispatch(IDispatch **pDispatch) +{ + if (pDispatch == NULL) + { + return E_INVALIDARG; + } + + *pDispatch = NULL; + return E_NOINTERFACE; +} diff --git a/webshell/embed/ActiveX/IEHtmlNode.h b/webshell/embed/ActiveX/IEHtmlNode.h index 7c1db046a055..6318160ee8f0 100644 --- a/webshell/embed/ActiveX/IEHtmlNode.h +++ b/webshell/embed/ActiveX/IEHtmlNode.h @@ -21,8 +21,8 @@ class CIEHtmlNode : public CComObjectRootEx { protected: - nsIDOMNode *m_pIDOMNode; - CIEHtmlNode *m_pParent; + nsIDOMNode *m_pIDOMNode; + IDispatch *m_pIDispParent; public: CIEHtmlNode(); @@ -32,7 +32,9 @@ protected: public: virtual HRESULT SetDOMNode(nsIDOMNode *pIDOMNode); virtual HRESULT GetDOMNode(nsIDOMNode **pIDOMNode); - virtual HRESULT SetParentNode(CIEHtmlNode *pParent); + virtual HRESULT GetDOMElement(nsIDOMElement **pIDOMElement); + virtual HRESULT SetParentNode(IDispatch *pIDispParent); + virtual HRESULT GetIDispatch(IDispatch **pDispatch); }; typedef CComObject CIEHtmlNodeInstance; diff --git a/webshell/embed/ActiveX/StdAfx.h b/webshell/embed/ActiveX/StdAfx.h index 6078d7667fc6..2f7f6c50bb43 100644 --- a/webshell/embed/ActiveX/StdAfx.h +++ b/webshell/embed/ActiveX/StdAfx.h @@ -104,6 +104,9 @@ typedef long int32; // Define some string classes typedef std::basic_string tstring; +#define CIPtr(iface) \ + CComQIPtr< iface, &IID_ ## iface > + #include "BrowserDiagnostics.h" #include "PropertyList.h" #include "MozillaControl.h"