1 /* 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "WebKitDLL.h" 28 #include "WebElementPropertyBag.h" 29 30 #include "MarshallingHelpers.h" 31 #include "DOMCoreClasses.h" 32 #include "WebFrame.h" 33 #pragma warning(push, 0) 34 #include <WebCore/Document.h> 35 #include <WebCore/Frame.h> 36 #include <WebCore/HitTestResult.h> 37 #include <WebCore/FrameLoader.h> 38 #include <WebCore/Image.h> 39 #include <WebCore/KURL.h> 40 #include <WebCore/RenderObject.h> 41 #pragma warning(pop) 42 43 using namespace WebCore; 44 45 // WebElementPropertyBag ----------------------------------------------- 46 WebElementPropertyBag::WebElementPropertyBag(const HitTestResult& result) 47 : m_result(new HitTestResult(result)) 48 , m_refCount(0) 49 { 50 gClassCount++; 51 gClassNameCount.add("WebElementPropertyBag"); 52 } 53 54 WebElementPropertyBag::~WebElementPropertyBag() 55 { 56 gClassCount--; 57 gClassNameCount.remove("WebElementPropertyBag"); 58 } 59 60 WebElementPropertyBag* WebElementPropertyBag::createInstance(const HitTestResult& result) 61 { 62 WebElementPropertyBag* instance = new WebElementPropertyBag(result); 63 instance->AddRef(); 64 65 return instance; 66 } 67 68 // IUnknown ------------------------------------------------------------------- 69 70 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::QueryInterface(REFIID riid, void** ppvObject) 71 { 72 *ppvObject = 0; 73 if (IsEqualGUID(riid, IID_IUnknown)) 74 *ppvObject = static_cast<IPropertyBag*>(this); 75 else if (IsEqualGUID(riid, IID_IPropertyBag)) 76 *ppvObject = static_cast<IPropertyBag*>(this); 77 else 78 return E_NOINTERFACE; 79 80 AddRef(); 81 return S_OK; 82 } 83 84 ULONG STDMETHODCALLTYPE WebElementPropertyBag::AddRef(void) 85 { 86 return ++m_refCount; 87 } 88 89 ULONG STDMETHODCALLTYPE WebElementPropertyBag::Release(void) 90 { 91 ULONG newRef = --m_refCount; 92 if (!newRef) 93 delete this; 94 95 return newRef; 96 } 97 98 static bool isEqual(LPCWSTR s1, LPCWSTR s2) 99 { 100 return !wcscmp(s1, s2); 101 } 102 103 static HRESULT convertStringToVariant(VARIANT* pVar, const String& string) 104 { 105 V_VT(pVar) = VT_BSTR; 106 V_BSTR(pVar) = SysAllocStringLen(string.characters(), string.length()); 107 if (string.length() && !V_BSTR(pVar)) 108 return E_OUTOFMEMORY; 109 110 return S_OK; 111 } 112 113 114 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/) 115 { 116 if (!pszPropName) 117 return E_POINTER; 118 119 if (!m_result) 120 return E_FAIL; 121 122 BSTR key = (BSTR)pszPropName; 123 VariantClear(pVar); 124 if (isEqual(WebElementDOMNodeKey, key)) { 125 IDOMNode* node = DOMNode::createInstance(m_result->innerNonSharedNode()); 126 V_VT(pVar) = VT_UNKNOWN; 127 V_UNKNOWN(pVar) = node; 128 return S_OK; 129 } else if (isEqual(WebElementFrameKey, key)) { 130 if (!(m_result->innerNonSharedNode() && m_result->innerNonSharedNode()->document() 131 && m_result->innerNonSharedNode()->document()->frame())) 132 return E_FAIL; 133 Frame* coreFrame = m_result->innerNonSharedNode()->document()->frame(); 134 WebFrame* webFrame = static_cast<WebFrame*>(coreFrame->loader()->client()); 135 IWebFrame* iWebFrame; 136 if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame))) 137 return E_FAIL; 138 V_VT(pVar) = VT_UNKNOWN; 139 V_UNKNOWN(pVar) = iWebFrame; 140 return S_OK; 141 } else if (isEqual(WebElementImageAltStringKey, key)) 142 return convertStringToVariant(pVar, m_result->altDisplayString()); 143 else if (isEqual(WebElementImageKey, key)) { 144 V_VT(pVar) = VT_BYREF; 145 V_BYREF(pVar) = m_result->image(); 146 return S_OK; 147 } else if (isEqual(WebElementImageRectKey, key)) { 148 V_VT(pVar) = VT_ARRAY; 149 IntRect boundingBox = m_result->innerNonSharedNode() && m_result->innerNonSharedNode()->renderer() ? 150 m_result->innerNonSharedNode()->renderer()->absoluteBoundingBoxRect(true) : IntRect(); 151 V_ARRAY(pVar) = MarshallingHelpers::intRectToSafeArray(boundingBox); 152 return S_OK; 153 } else if (isEqual(WebElementImageURLKey, key)) 154 return convertStringToVariant(pVar, m_result->absoluteImageURL().string()); 155 else if (isEqual(WebElementIsSelectedKey, key)) { 156 V_VT(pVar) = VT_BOOL; 157 if (m_result->isSelected()) 158 V_BOOL(pVar) = VARIANT_TRUE; 159 else 160 V_BOOL(pVar) = VARIANT_FALSE; 161 return S_OK; 162 } else if (isEqual(WebElementSpellingToolTipKey, key)) { 163 TextDirection dir; 164 return convertStringToVariant(pVar, m_result->spellingToolTip(dir)); 165 } else if (isEqual(WebElementTitleKey, key)) { 166 TextDirection dir; 167 return convertStringToVariant(pVar, m_result->title(dir)); 168 } 169 else if (isEqual(WebElementLinkURLKey, key)) 170 return convertStringToVariant(pVar, m_result->absoluteLinkURL().string()); 171 else if (isEqual(WebElementLinkTargetFrameKey, key)) { 172 if (!m_result->targetFrame()) 173 return E_FAIL; 174 WebFrame* webFrame = kit(m_result->targetFrame()); 175 IWebFrame* iWebFrame; 176 if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame))) 177 return E_FAIL; 178 V_VT(pVar) = VT_UNKNOWN; 179 V_UNKNOWN(pVar) = iWebFrame; 180 return S_OK; 181 } else if (isEqual(WebElementLinkTitleKey, key)) 182 return convertStringToVariant(pVar, m_result->titleDisplayString()); 183 else if (isEqual(WebElementLinkLabelKey, key)) 184 return convertStringToVariant(pVar, m_result->textContent()); 185 else if (isEqual(WebElementIsContentEditableKey, key)) { 186 V_VT(pVar) = VT_BOOL; 187 if (m_result->isContentEditable()) 188 V_BOOL(pVar) = VARIANT_TRUE; 189 else 190 V_BOOL(pVar) = VARIANT_FALSE; 191 return S_OK; 192 } 193 194 return E_INVALIDARG; 195 } 196 197 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar) 198 { 199 if (!pszPropName || !pVar) 200 return E_POINTER; 201 202 return E_FAIL; 203 } 204