/* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "WebKitDLL.h" #include "WebBackForwardList.h" #include "WebFrame.h" #include "WebKit.h" #include "WebPreferences.h" #include <WebCore/BackForwardListImpl.h> #include <WebCore/COMPtr.h> #include <WebCore/HistoryItem.h> using std::min; using namespace WebCore; // WebBackForwardList ---------------------------------------------------------------- // FIXME: Instead of this we could just create a class derived from BackForwardListImpl // with a pointer to a WebBackForwardList in it. static HashMap<BackForwardListImpl*, WebBackForwardList*>& backForwardListWrappers() { static HashMap<BackForwardListImpl*, WebBackForwardList*> staticBackForwardListWrappers; return staticBackForwardListWrappers; } WebBackForwardList::WebBackForwardList(PassRefPtr<BackForwardListImpl> backForwardList) : m_refCount(0) , m_backForwardList(backForwardList) { ASSERT(!backForwardListWrappers().contains(m_backForwardList.get())); backForwardListWrappers().set(m_backForwardList.get(), this); gClassCount++; gClassNameCount.add("WebBackForwardList"); } WebBackForwardList::~WebBackForwardList() { ASSERT(m_backForwardList->closed()); ASSERT(backForwardListWrappers().contains(m_backForwardList.get())); backForwardListWrappers().remove(m_backForwardList.get()); gClassCount--; gClassNameCount.remove("WebBackForwardList"); } WebBackForwardList* WebBackForwardList::createInstance(PassRefPtr<BackForwardListImpl> backForwardList) { WebBackForwardList* instance; instance = backForwardListWrappers().get(backForwardList.get()); if (!instance) instance = new WebBackForwardList(backForwardList); instance->AddRef(); return instance; } // IUnknown ------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE WebBackForwardList::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IUnknown)) *ppvObject = static_cast<IWebBackForwardList*>(this); else if (IsEqualGUID(riid, IID_IWebBackForwardList)) *ppvObject = static_cast<IWebBackForwardList*>(this); else if (IsEqualGUID(riid, IID_IWebBackForwardListPrivate)) *ppvObject = static_cast<IWebBackForwardListPrivate*>(this); else return E_NOINTERFACE; AddRef(); return S_OK; } ULONG STDMETHODCALLTYPE WebBackForwardList::AddRef(void) { return ++m_refCount; } ULONG STDMETHODCALLTYPE WebBackForwardList::Release(void) { ULONG newRef = --m_refCount; if (!newRef) delete(this); return newRef; } // IWebBackForwardList --------------------------------------------------------- HRESULT STDMETHODCALLTYPE WebBackForwardList::addItem( /* [in] */ IWebHistoryItem* item) { COMPtr<WebHistoryItem> webHistoryItem; if (!item || FAILED(item->QueryInterface(&webHistoryItem))) return E_FAIL; m_backForwardList->addItem(webHistoryItem->historyItem()); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::goBack( void) { m_backForwardList->goBack(); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::goForward( void) { m_backForwardList->goForward(); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::goToItem( /* [in] */ IWebHistoryItem* item) { COMPtr<WebHistoryItem> webHistoryItem; if (!item || FAILED(item->QueryInterface(&webHistoryItem))) return E_FAIL; m_backForwardList->goToItem(webHistoryItem->historyItem()); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::backItem( /* [retval][out] */ IWebHistoryItem** item) { if (!item) return E_POINTER; HistoryItem* historyItem = m_backForwardList->backItem(); if (!historyItem) return E_FAIL; *item = WebHistoryItem::createInstance(historyItem); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::currentItem( /* [retval][out] */ IWebHistoryItem** item) { if (!item) return E_POINTER; HistoryItem* historyItem = m_backForwardList->currentItem(); if (!historyItem) return E_FAIL; *item = WebHistoryItem::createInstance(historyItem); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardItem( /* [retval][out] */ IWebHistoryItem** item) { if (!item) return E_POINTER; HistoryItem* historyItem = m_backForwardList->forwardItem(); if (!historyItem) return E_FAIL; *item = WebHistoryItem::createInstance(historyItem); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::backListWithLimit( /* [in] */ int limit, /* [out] */ int* listCount, /* [retval][out] */ IWebHistoryItem** list) { HistoryItemVector historyItemVector; m_backForwardList->backListWithLimit(limit, historyItemVector); *listCount = static_cast<int>(historyItemVector.size()); if (list) for (unsigned i = 0; i < historyItemVector.size(); i++) list[i] = WebHistoryItem::createInstance(historyItemVector[i].get()); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardListWithLimit( /* [in] */ int limit, /* [out] */ int* listCount, /* [retval][out] */ IWebHistoryItem** list) { HistoryItemVector historyItemVector; m_backForwardList->forwardListWithLimit(limit, historyItemVector); *listCount = static_cast<int>(historyItemVector.size()); if (list) for (unsigned i = 0; i < historyItemVector.size(); i++) list[i] = WebHistoryItem::createInstance(historyItemVector[i].get()); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::capacity( /* [retval][out] */ int* result) { *result = (int)m_backForwardList->capacity(); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::setCapacity( /* [in] */ int size) { if (size < 0) return E_FAIL; m_backForwardList->setCapacity(size); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::backListCount( /* [retval][out] */ int* count) { *count = m_backForwardList->backListCount(); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::forwardListCount( /* [retval][out] */ int* count) { *count = m_backForwardList->forwardListCount(); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::containsItem( /* [in] */ IWebHistoryItem* item, /* [retval][out] */ BOOL* result) { COMPtr<WebHistoryItem> webHistoryItem; if (!item || FAILED(item->QueryInterface(&webHistoryItem))) return E_FAIL; *result = m_backForwardList->containsItem(webHistoryItem->historyItem()); return S_OK; } HRESULT STDMETHODCALLTYPE WebBackForwardList::itemAtIndex( /* [in] */ int index, /* [retval][out] */ IWebHistoryItem** item) { if (!item) return E_POINTER; HistoryItem* historyItem = m_backForwardList->itemAtIndex(index); if (!historyItem) return E_FAIL; *item = WebHistoryItem::createInstance(historyItem); return S_OK; } // IWebBackForwardListPrivate -------------------------------------------------------- HRESULT STDMETHODCALLTYPE WebBackForwardList::removeItem( /* [in] */ IWebHistoryItem* item) { COMPtr<WebHistoryItem> webHistoryItem; if (!item || FAILED(item->QueryInterface(&webHistoryItem))) return E_FAIL; m_backForwardList->removeItem(webHistoryItem->historyItem()); return S_OK; }