initial import
[vuplus_webkit] / Source / WebKit / win / WebElementPropertyBag.cpp
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 #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>
40
41 using namespace WebCore;
42
43 // WebElementPropertyBag -----------------------------------------------
44 WebElementPropertyBag::WebElementPropertyBag(const HitTestResult& result)
45     : m_result(adoptPtr(new HitTestResult(result)))
46     , m_refCount(0)
47 {
48     gClassCount++;
49     gClassNameCount.add("WebElementPropertyBag");
50 }
51
52 WebElementPropertyBag::~WebElementPropertyBag()
53 {
54     gClassCount--;
55     gClassNameCount.remove("WebElementPropertyBag");
56 }
57
58 WebElementPropertyBag* WebElementPropertyBag::createInstance(const HitTestResult& result)
59 {
60     WebElementPropertyBag* instance = new WebElementPropertyBag(result); 
61     instance->AddRef();
62
63     return instance;
64 }
65
66 // IUnknown -------------------------------------------------------------------
67
68 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
69 {
70     *ppvObject = 0;
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);
75     else
76         return E_NOINTERFACE;
77
78     AddRef();
79     return S_OK;
80 }
81
82 ULONG STDMETHODCALLTYPE WebElementPropertyBag::AddRef(void)
83 {
84     return ++m_refCount;
85 }
86
87 ULONG STDMETHODCALLTYPE WebElementPropertyBag::Release(void)
88 {
89     ULONG newRef = --m_refCount;
90     if (!newRef)
91         delete this;
92
93     return newRef;
94 }
95
96 static bool isEqual(LPCWSTR s1, LPCWSTR s2)
97 {
98     return !wcscmp(s1, s2);
99 }
100
101 static HRESULT convertStringToVariant(VARIANT* pVar, const String& string)
102 {
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;
107
108     return S_OK;
109 }
110
111
112 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/)
113 {
114     if (!pszPropName)
115         return E_POINTER;
116
117     if (!m_result)
118         return E_FAIL;
119
120     BSTR key = (BSTR)pszPropName;
121     VariantClear(pVar);
122     if (isEqual(WebElementDOMNodeKey, key)) {
123         IDOMNode* node = DOMNode::createInstance(m_result->innerNonSharedNode());
124         V_VT(pVar) = VT_UNKNOWN;
125         V_UNKNOWN(pVar) = node;
126         return S_OK;
127     } else if (isEqual(WebElementFrameKey, key)) {
128         if (!(m_result->innerNonSharedNode() && m_result->innerNonSharedNode()->document()
129            && m_result->innerNonSharedNode()->document()->frame()))
130             return E_FAIL;
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)))
135             return E_FAIL;
136         V_VT(pVar) = VT_UNKNOWN;
137         V_UNKNOWN(pVar) = iWebFrame;
138         return S_OK;
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();
144         return S_OK;
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);
150         return S_OK;
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;
157         else
158             V_BOOL(pVar) = VARIANT_FALSE;
159         return S_OK;
160     }
161     if (isEqual(WebElementMediaURLKey, key))
162         return convertStringToVariant(pVar, m_result->absoluteMediaURL().string());
163     if (isEqual(WebElementSpellingToolTipKey, key)) {
164         TextDirection dir;
165         return convertStringToVariant(pVar, m_result->spellingToolTip(dir));
166     } else if (isEqual(WebElementTitleKey, key)) {
167         TextDirection dir;
168         return convertStringToVariant(pVar, m_result->title(dir));
169     }
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())
174             return E_FAIL;
175         WebFrame* webFrame = kit(m_result->targetFrame());
176         IWebFrame* iWebFrame;
177         if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame)))
178             return E_FAIL;
179         V_VT(pVar) = VT_UNKNOWN;
180         V_UNKNOWN(pVar) = iWebFrame;
181         return S_OK;
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;
190         else
191             V_BOOL(pVar) = VARIANT_FALSE;
192         return S_OK;
193     }
194
195     return E_INVALIDARG;
196 }
197
198 HRESULT STDMETHODCALLTYPE WebElementPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
199 {
200     if (!pszPropName || !pVar)
201         return E_POINTER;
202
203     return E_FAIL;
204 }