Rename Source/WebKit to Source/WebKitLegacy.
[WebKit-https.git] / Source / WebKitLegacy / win / WebElementPropertyBag.cpp
1 /*
2  * Copyright (C) 2006-2007, 2013, 2015 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 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 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 "WebKitDLL.h"
27 #include "WebElementPropertyBag.h"
28
29 #include "MarshallingHelpers.h"
30 #include "DOMCoreClasses.h"
31 #include "WebFrame.h"
32 #include "WebFrameLoaderClient.h"
33 #include <WebCore/BString.h>
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/URL.h>
40 #include <WebCore/RenderObject.h>
41
42 using namespace WebCore;
43
44 // WebElementPropertyBag -----------------------------------------------
45 WebElementPropertyBag::WebElementPropertyBag(const HitTestResult& result)
46     : m_result(std::make_unique<HitTestResult>(result))
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 WebElementPropertyBag::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
69 {
70     if (!ppvObject)
71         return E_POINTER;
72     *ppvObject = nullptr;
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 WebElementPropertyBag::AddRef()
85 {
86     return ++m_refCount;
87 }
88
89 ULONG WebElementPropertyBag::Release()
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) = BString(string).release();
107     if (string.length() && !V_BSTR(pVar))
108         return E_OUTOFMEMORY;
109
110     return S_OK;
111 }
112
113
114 HRESULT 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().frame()))
131             return E_FAIL;
132         Frame* coreFrame = m_result->innerNonSharedNode()->document().frame();
133         WebFrame* webFrame = static_cast<WebFrameLoaderClient&>(coreFrame->loader().client()).webFrame();
134         IWebFrame* iWebFrame;
135         if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame)))
136             return E_FAIL;
137         V_VT(pVar) = VT_UNKNOWN;
138         V_UNKNOWN(pVar) = iWebFrame;
139         return S_OK;
140     } else if (isEqual(WebElementImageAltStringKey, key))
141         return convertStringToVariant(pVar, m_result->altDisplayString());
142     else if (isEqual(WebElementImageKey, key)) {
143         V_VT(pVar) = VT_BYREF;
144         V_BYREF(pVar) = m_result->image();
145         return S_OK;
146     } else if (isEqual(WebElementImageRectKey, key)) {
147         V_VT(pVar) = VT_ARRAY;
148         IntRect boundingBox = m_result->innerNonSharedNode() && m_result->innerNonSharedNode()->renderer() ?
149                                 m_result->innerNonSharedNode()->renderer()->absoluteBoundingBoxRect(true) : IntRect();
150         V_ARRAY(pVar) = MarshallingHelpers::intRectToSafeArray(boundingBox);
151         return S_OK;
152     } else if (isEqual(WebElementImageURLKey, key))
153         return convertStringToVariant(pVar, m_result->absoluteImageURL().string());
154     else if (isEqual(WebElementIsSelectedKey, key)) {
155         V_VT(pVar) = VT_BOOL;
156         if (m_result->isSelected())
157             V_BOOL(pVar) = VARIANT_TRUE;
158         else
159             V_BOOL(pVar) = VARIANT_FALSE;
160         return S_OK;
161     }
162     if (isEqual(WebElementMediaURLKey, key))
163         return convertStringToVariant(pVar, m_result->absoluteMediaURL().string());
164     if (isEqual(WebElementSpellingToolTipKey, key)) {
165         TextDirection dir;
166         return convertStringToVariant(pVar, m_result->spellingToolTip(dir));
167     } else if (isEqual(WebElementTitleKey, key)) {
168         TextDirection dir;
169         return convertStringToVariant(pVar, m_result->title(dir));
170     }
171     else if (isEqual(WebElementLinkURLKey, key))
172         return convertStringToVariant(pVar, m_result->absoluteLinkURL().string());
173     else if (isEqual(WebElementLinkTargetFrameKey, key)) {
174         if (!m_result->targetFrame())
175             return E_FAIL;
176         WebFrame* webFrame = kit(m_result->targetFrame());
177         IWebFrame* iWebFrame;
178         if (FAILED(webFrame->QueryInterface(IID_IWebFrame, (void**)&iWebFrame)))
179             return E_FAIL;
180         V_VT(pVar) = VT_UNKNOWN;
181         V_UNKNOWN(pVar) = iWebFrame;
182         return S_OK;
183     } else if (isEqual(WebElementLinkTitleKey, key))
184         return convertStringToVariant(pVar, m_result->titleDisplayString());
185     else if (isEqual(WebElementLinkLabelKey, key))
186         return convertStringToVariant(pVar, m_result->textContent());
187     else if (isEqual(WebElementIsContentEditableKey, key)) {
188         V_VT(pVar) = VT_BOOL;
189         if (m_result->isContentEditable())
190             V_BOOL(pVar) = VARIANT_TRUE;
191         else
192             V_BOOL(pVar) = VARIANT_FALSE;
193         return S_OK;
194     }
195
196     return E_INVALIDARG;
197 }
198
199 HRESULT WebElementPropertyBag::Write(_In_ LPCOLESTR pszPropName, _In_ VARIANT* pVar)
200 {
201     if (!pszPropName || !pVar)
202         return E_POINTER;
203
204     return E_NOTIMPL;
205 }