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