2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebKitDLL.h"
28 #include "WebElementPropertyBag.h"
30 #include "MarshallingHelpers.h"
31 #include "DOMCoreClasses.h"
33 #include <WebCore/Document.h>
34 #include <WebCore/Frame.h>
35 #include <WebCore/HitTestResult.h>
36 #include <WebCore/FrameLoader.h>
37 #include <WebCore/Image.h>
38 #include <WebCore/KURL.h>
39 #include <WebCore/RenderObject.h>
41 using namespace WebCore;
43 // WebElementPropertyBag -----------------------------------------------
44 WebElementPropertyBag::WebElementPropertyBag(const HitTestResult& result)
45 : m_result(adoptPtr(new HitTestResult(result)))
49 gClassNameCount.add("WebElementPropertyBag");
52 WebElementPropertyBag::~WebElementPropertyBag()
55 gClassNameCount.remove("WebElementPropertyBag");
58 WebElementPropertyBag* WebElementPropertyBag::createInstance(const HitTestResult& result)
60 WebElementPropertyBag* instance = new WebElementPropertyBag(result);
66 // IUnknown -------------------------------------------------------------------
68 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
71 if (IsEqualGUID(riid, IID_IUnknown))
72 *ppvObject = static_cast<IPropertyBag*>(this);
73 else if (IsEqualGUID(riid, IID_IPropertyBag))
74 *ppvObject = static_cast<IPropertyBag*>(this);
82 ULONG STDMETHODCALLTYPE WebElementPropertyBag::AddRef(void)
87 ULONG STDMETHODCALLTYPE WebElementPropertyBag::Release(void)
89 ULONG newRef = --m_refCount;
96 static bool isEqual(LPCWSTR s1, LPCWSTR s2)
98 return !wcscmp(s1, s2);
101 static HRESULT convertStringToVariant(VARIANT* pVar, const String& string)
103 V_VT(pVar) = VT_BSTR;
104 V_BSTR(pVar) = SysAllocStringLen(string.characters(), string.length());
105 if (string.length() && !V_BSTR(pVar))
106 return E_OUTOFMEMORY;
112 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/)
120 BSTR key = (BSTR)pszPropName;
122 if (isEqual(WebElementDOMNodeKey, key)) {
123 IDOMNode* node = DOMNode::createInstance(m_result->innerNonSharedNode());
124 V_VT(pVar) = VT_UNKNOWN;
125 V_UNKNOWN(pVar) = node;
127 } else if (isEqual(WebElementFrameKey, key)) {
128 if (!(m_result->innerNonSharedNode() && m_result->innerNonSharedNode()->document()
129 && m_result->innerNonSharedNode()->document()->frame()))
131 Frame* coreFrame = m_result->innerNonSharedNode()->document()->frame();
132 WebFrame* webFrame = static_cast<WebFrame*>(coreFrame->loader()->client());
133 IWebFrame* iWebFrame;
134 if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame)))
136 V_VT(pVar) = VT_UNKNOWN;
137 V_UNKNOWN(pVar) = iWebFrame;
139 } else if (isEqual(WebElementImageAltStringKey, key))
140 return convertStringToVariant(pVar, m_result->altDisplayString());
141 else if (isEqual(WebElementImageKey, key)) {
142 V_VT(pVar) = VT_BYREF;
143 V_BYREF(pVar) = m_result->image();
145 } else if (isEqual(WebElementImageRectKey, key)) {
146 V_VT(pVar) = VT_ARRAY;
147 IntRect boundingBox = m_result->innerNonSharedNode() && m_result->innerNonSharedNode()->renderer() ?
148 m_result->innerNonSharedNode()->renderer()->absoluteBoundingBoxRect(true) : IntRect();
149 V_ARRAY(pVar) = MarshallingHelpers::intRectToSafeArray(boundingBox);
151 } else if (isEqual(WebElementImageURLKey, key))
152 return convertStringToVariant(pVar, m_result->absoluteImageURL().string());
153 else if (isEqual(WebElementIsSelectedKey, key)) {
154 V_VT(pVar) = VT_BOOL;
155 if (m_result->isSelected())
156 V_BOOL(pVar) = VARIANT_TRUE;
158 V_BOOL(pVar) = VARIANT_FALSE;
161 if (isEqual(WebElementMediaURLKey, key))
162 return convertStringToVariant(pVar, m_result->absoluteMediaURL().string());
163 if (isEqual(WebElementSpellingToolTipKey, key)) {
165 return convertStringToVariant(pVar, m_result->spellingToolTip(dir));
166 } else if (isEqual(WebElementTitleKey, key)) {
168 return convertStringToVariant(pVar, m_result->title(dir));
170 else if (isEqual(WebElementLinkURLKey, key))
171 return convertStringToVariant(pVar, m_result->absoluteLinkURL().string());
172 else if (isEqual(WebElementLinkTargetFrameKey, key)) {
173 if (!m_result->targetFrame())
175 WebFrame* webFrame = kit(m_result->targetFrame());
176 IWebFrame* iWebFrame;
177 if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame)))
179 V_VT(pVar) = VT_UNKNOWN;
180 V_UNKNOWN(pVar) = iWebFrame;
182 } else if (isEqual(WebElementLinkTitleKey, key))
183 return convertStringToVariant(pVar, m_result->titleDisplayString());
184 else if (isEqual(WebElementLinkLabelKey, key))
185 return convertStringToVariant(pVar, m_result->textContent());
186 else if (isEqual(WebElementIsContentEditableKey, key)) {
187 V_VT(pVar) = VT_BOOL;
188 if (m_result->isContentEditable())
189 V_BOOL(pVar) = VARIANT_TRUE;
191 V_BOOL(pVar) = VARIANT_FALSE;
198 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
200 if (!pszPropName || !pVar)