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 "WebBackForwardList.h"
29
30 #include "COMPtr.h"
31 #include "WebFrame.h"
32 #include "WebKit.h"
33 #include "WebPreferences.h"
34
35 #include <WebCore/BackForwardList.h>
36 #include <WebCore/HistoryItem.h>
37
38 using std::min;
39 using namespace WebCore;
40
41 // WebBackForwardList ----------------------------------------------------------------
42
backForwardListWrappers()43 static HashMap<BackForwardList*, WebBackForwardList*>& backForwardListWrappers()
44 {
45 static HashMap<BackForwardList*, WebBackForwardList*> staticBackForwardListWrappers;
46 return staticBackForwardListWrappers;
47 }
48
WebBackForwardList(PassRefPtr<BackForwardList> backForwardList)49 WebBackForwardList::WebBackForwardList(PassRefPtr<BackForwardList> backForwardList)
50 : m_refCount(0)
51 , m_backForwardList(backForwardList)
52 {
53 ASSERT(!backForwardListWrappers().contains(m_backForwardList.get()));
54 backForwardListWrappers().set(m_backForwardList.get(), this);
55
56 gClassCount++;
57 gClassNameCount.add("WebBackForwardList");
58 }
59
~WebBackForwardList()60 WebBackForwardList::~WebBackForwardList()
61 {
62 ASSERT(m_backForwardList->closed());
63
64 ASSERT(backForwardListWrappers().contains(m_backForwardList.get()));
65 backForwardListWrappers().remove(m_backForwardList.get());
66
67 gClassCount--;
68 gClassNameCount.remove("WebBackForwardList");
69 }
70
createInstance(PassRefPtr<BackForwardList> backForwardList)71 WebBackForwardList* WebBackForwardList::createInstance(PassRefPtr<BackForwardList> backForwardList)
72 {
73 WebBackForwardList* instance;
74
75 instance = backForwardListWrappers().get(backForwardList.get());
76
77 if (!instance)
78 instance = new WebBackForwardList(backForwardList);
79
80 instance->AddRef();
81 return instance;
82 }
83
84 // IUnknown -------------------------------------------------------------------
85
QueryInterface(REFIID riid,void ** ppvObject)86 HRESULT STDMETHODCALLTYPE WebBackForwardList::QueryInterface(REFIID riid, void** ppvObject)
87 {
88 *ppvObject = 0;
89 if (IsEqualGUID(riid, IID_IUnknown))
90 *ppvObject = static_cast<IWebBackForwardList*>(this);
91 else if (IsEqualGUID(riid, IID_IWebBackForwardList))
92 *ppvObject = static_cast<IWebBackForwardList*>(this);
93 else if (IsEqualGUID(riid, IID_IWebBackForwardListPrivate))
94 *ppvObject = static_cast<IWebBackForwardListPrivate*>(this);
95 else
96 return E_NOINTERFACE;
97
98 AddRef();
99 return S_OK;
100 }
101
AddRef(void)102 ULONG STDMETHODCALLTYPE WebBackForwardList::AddRef(void)
103 {
104 return ++m_refCount;
105 }
106
Release(void)107 ULONG STDMETHODCALLTYPE WebBackForwardList::Release(void)
108 {
109 ULONG newRef = --m_refCount;
110 if (!newRef)
111 delete(this);
112
113 return newRef;
114 }
115
116 // IWebBackForwardList ---------------------------------------------------------
117
addItem(IWebHistoryItem * item)118 HRESULT STDMETHODCALLTYPE WebBackForwardList::addItem(
119 /* [in] */ IWebHistoryItem* item)
120 {
121 COMPtr<WebHistoryItem> webHistoryItem;
122
123 if (!item || FAILED(item->QueryInterface(&webHistoryItem)))
124 return E_FAIL;
125
126 m_backForwardList->addItem(webHistoryItem->historyItem());
127 return S_OK;
128 }
129
goBack(void)130 HRESULT STDMETHODCALLTYPE WebBackForwardList::goBack( void)
131 {
132 m_backForwardList->goBack();
133 return S_OK;
134 }
135
goForward(void)136 HRESULT STDMETHODCALLTYPE WebBackForwardList::goForward( void)
137 {
138 m_backForwardList->goForward();
139 return S_OK;
140 }
141
goToItem(IWebHistoryItem * item)142 HRESULT STDMETHODCALLTYPE WebBackForwardList::goToItem(
143 /* [in] */ IWebHistoryItem* item)
144 {
145 COMPtr<WebHistoryItem> webHistoryItem;
146
147 if (!item || FAILED(item->QueryInterface(&webHistoryItem)))
148 return E_FAIL;
149
150 m_backForwardList->goToItem(webHistoryItem->historyItem());
151 return S_OK;
152 }
153
backItem(IWebHistoryItem ** item)154 HRESULT STDMETHODCALLTYPE WebBackForwardList::backItem(
155 /* [retval][out] */ IWebHistoryItem** item)
156 {
157 if (!item)
158 return E_POINTER;
159
160 HistoryItem* historyItem = m_backForwardList->backItem();
161
162 if (!historyItem)
163 return E_FAIL;
164
165 *item = WebHistoryItem::createInstance(historyItem);
166 return S_OK;
167 }
168
currentItem(IWebHistoryItem ** item)169 HRESULT STDMETHODCALLTYPE WebBackForwardList::currentItem(
170 /* [retval][out] */ IWebHistoryItem** item)
171 {
172 if (!item)
173 return E_POINTER;
174
175 HistoryItem* historyItem = m_backForwardList->currentItem();
176
177 if (!historyItem)
178 return E_FAIL;
179
180 *item = WebHistoryItem::createInstance(historyItem);
181 return S_OK;
182 }
183
forwardItem(IWebHistoryItem ** item)184 HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardItem(
185 /* [retval][out] */ IWebHistoryItem** item)
186 {
187 if (!item)
188 return E_POINTER;
189
190 HistoryItem* historyItem = m_backForwardList->forwardItem();
191
192 if (!historyItem)
193 return E_FAIL;
194
195 *item = WebHistoryItem::createInstance(historyItem);
196 return S_OK;
197 }
198
backListWithLimit(int limit,int * listCount,IWebHistoryItem ** list)199 HRESULT STDMETHODCALLTYPE WebBackForwardList::backListWithLimit(
200 /* [in] */ int limit,
201 /* [out] */ int* listCount,
202 /* [retval][out] */ IWebHistoryItem** list)
203 {
204 HistoryItemVector historyItemVector;
205 m_backForwardList->backListWithLimit(limit, historyItemVector);
206
207 *listCount = static_cast<int>(historyItemVector.size());
208
209 if (list)
210 for (unsigned i = 0; i < historyItemVector.size(); i++)
211 list[i] = WebHistoryItem::createInstance(historyItemVector[i].get());
212
213 return S_OK;
214 }
215
forwardListWithLimit(int limit,int * listCount,IWebHistoryItem ** list)216 HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardListWithLimit(
217 /* [in] */ int limit,
218 /* [out] */ int* listCount,
219 /* [retval][out] */ IWebHistoryItem** list)
220 {
221 HistoryItemVector historyItemVector;
222 m_backForwardList->forwardListWithLimit(limit, historyItemVector);
223
224 *listCount = static_cast<int>(historyItemVector.size());
225
226 if (list)
227 for (unsigned i = 0; i < historyItemVector.size(); i++)
228 list[i] = WebHistoryItem::createInstance(historyItemVector[i].get());
229
230 return S_OK;
231 }
232
capacity(int * result)233 HRESULT STDMETHODCALLTYPE WebBackForwardList::capacity(
234 /* [retval][out] */ int* result)
235 {
236 *result = (int)m_backForwardList->capacity();
237 return S_OK;
238 }
239
setCapacity(int size)240 HRESULT STDMETHODCALLTYPE WebBackForwardList::setCapacity(
241 /* [in] */ int size)
242 {
243 if (size < 0)
244 return E_FAIL;
245
246 m_backForwardList->setCapacity(size);
247 return S_OK;
248 }
249
backListCount(int * count)250 HRESULT STDMETHODCALLTYPE WebBackForwardList::backListCount(
251 /* [retval][out] */ int* count)
252 {
253 *count = m_backForwardList->backListCount();
254 return S_OK;
255 }
256
forwardListCount(int * count)257 HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardListCount(
258 /* [retval][out] */ int* count)
259 {
260 *count = m_backForwardList->forwardListCount();
261 return S_OK;
262 }
263
containsItem(IWebHistoryItem * item,BOOL * result)264 HRESULT STDMETHODCALLTYPE WebBackForwardList::containsItem(
265 /* [in] */ IWebHistoryItem* item,
266 /* [retval][out] */ BOOL* result)
267 {
268 COMPtr<WebHistoryItem> webHistoryItem;
269
270 if (!item || FAILED(item->QueryInterface(&webHistoryItem)))
271 return E_FAIL;
272
273 *result = m_backForwardList->containsItem(webHistoryItem->historyItem());
274 return S_OK;
275 }
276
itemAtIndex(int index,IWebHistoryItem ** item)277 HRESULT STDMETHODCALLTYPE WebBackForwardList::itemAtIndex(
278 /* [in] */ int index,
279 /* [retval][out] */ IWebHistoryItem** item)
280 {
281 if (!item)
282 return E_POINTER;
283
284 HistoryItem* historyItem = m_backForwardList->itemAtIndex(index);
285
286 if (!historyItem)
287 return E_FAIL;
288
289 *item = WebHistoryItem::createInstance(historyItem);
290 return S_OK;
291 }
292
293 // IWebBackForwardListPrivate --------------------------------------------------------
294
removeItem(IWebHistoryItem * item)295 HRESULT STDMETHODCALLTYPE WebBackForwardList::removeItem(
296 /* [in] */ IWebHistoryItem* item)
297 {
298 COMPtr<WebHistoryItem> webHistoryItem;
299
300 if (!item || FAILED(item->QueryInterface(&webHistoryItem)))
301 return E_FAIL;
302
303 m_backForwardList->removeItem(webHistoryItem->historyItem());
304 return S_OK;
305 }
306