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 "WebFrame.h" 31 #include "WebKit.h" 32 #include "WebPreferences.h" 33 34 #include <WebCore/BackForwardListImpl.h> 35 #include <WebCore/COMPtr.h> 36 #include <WebCore/HistoryItem.h> 37 38 using std::min; 39 using namespace WebCore; 40 41 // WebBackForwardList ---------------------------------------------------------------- 42 43 // FIXME: Instead of this we could just create a class derived from BackForwardListImpl 44 // with a pointer to a WebBackForwardList in it. 45 static HashMap<BackForwardListImpl*, WebBackForwardList*>& backForwardListWrappers() 46 { 47 static HashMap<BackForwardListImpl*, WebBackForwardList*> staticBackForwardListWrappers; 48 return staticBackForwardListWrappers; 49 } 50 51 WebBackForwardList::WebBackForwardList(PassRefPtr<BackForwardListImpl> 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 62 WebBackForwardList::~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 73 WebBackForwardList* WebBackForwardList::createInstance(PassRefPtr<BackForwardListImpl> 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 88 HRESULT 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 104 ULONG STDMETHODCALLTYPE WebBackForwardList::AddRef(void) 105 { 106 return ++m_refCount; 107 } 108 109 ULONG 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 120 HRESULT 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 132 HRESULT STDMETHODCALLTYPE WebBackForwardList::goBack( void) 133 { 134 m_backForwardList->goBack(); 135 return S_OK; 136 } 137 138 HRESULT STDMETHODCALLTYPE WebBackForwardList::goForward( void) 139 { 140 m_backForwardList->goForward(); 141 return S_OK; 142 } 143 144 HRESULT 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 156 HRESULT 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 171 HRESULT 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 186 HRESULT 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 201 HRESULT 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 218 HRESULT 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 235 HRESULT STDMETHODCALLTYPE WebBackForwardList::capacity( 236 /* [retval][out] */ int* result) 237 { 238 *result = (int)m_backForwardList->capacity(); 239 return S_OK; 240 } 241 242 HRESULT 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 252 HRESULT STDMETHODCALLTYPE WebBackForwardList::backListCount( 253 /* [retval][out] */ int* count) 254 { 255 *count = m_backForwardList->backListCount(); 256 return S_OK; 257 } 258 259 HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardListCount( 260 /* [retval][out] */ int* count) 261 { 262 *count = m_backForwardList->forwardListCount(); 263 return S_OK; 264 } 265 266 HRESULT 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 279 HRESULT 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 297 HRESULT 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