WebKit2/UIProcess/WebBackForwardList.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 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. AND ITS CONTRIBUTORS ``AS IS''
       
    14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
       
    17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
    21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
       
    23  * THE POSSIBILITY OF SUCH DAMAGE.
       
    24  */
       
    25 
       
    26 #include "WebBackForwardList.h"
       
    27 
       
    28 #include "WebPageProxy.h"
       
    29 
       
    30 namespace WebKit {
       
    31 
       
    32 static const unsigned DefaultCapacity = 100;
       
    33 static const unsigned NoCurrentItemIndex = UINT_MAX;
       
    34 
       
    35 WebBackForwardList::WebBackForwardList(WebPageProxy* page)
       
    36     : m_page(page)
       
    37     , m_current(NoCurrentItemIndex)
       
    38     , m_capacity(DefaultCapacity)
       
    39     , m_closed(true)
       
    40     , m_enabled(true)
       
    41 {
       
    42 }
       
    43 
       
    44 WebBackForwardList::~WebBackForwardList()
       
    45 {
       
    46 }
       
    47 
       
    48 void WebBackForwardList::addItem(WebBackForwardListItem* newItem)
       
    49 {
       
    50     if (m_capacity == 0 || !m_enabled)
       
    51         return;
       
    52     
       
    53     // Toss anything in the forward list    
       
    54     if (m_current != NoCurrentItemIndex) {
       
    55         unsigned targetSize = m_current + 1;
       
    56         while (m_entries.size() > targetSize) {
       
    57             RefPtr<WebBackForwardListItem> item = m_entries.last();
       
    58             m_entries.removeLast();
       
    59         }
       
    60     }
       
    61 
       
    62     // Toss the first item if the list is getting too big, as long as we're not using it
       
    63     // (or even if we are, if we only want 1 entry).
       
    64     if (m_entries.size() == m_capacity && (m_current != 0 || m_capacity == 1)) {
       
    65         RefPtr<WebBackForwardListItem> item = m_entries[0];
       
    66         m_entries.remove(0);
       
    67         m_current--;
       
    68         
       
    69         if (m_page)
       
    70             m_page->didChangeBackForwardList();
       
    71     }
       
    72 
       
    73     m_entries.insert(m_current + 1, newItem);
       
    74     m_current++;
       
    75 
       
    76     if (m_page)
       
    77         m_page->didChangeBackForwardList();
       
    78 }
       
    79 
       
    80 void WebBackForwardList::goToItem(WebBackForwardListItem* item)
       
    81 {
       
    82     if (!m_entries.size() || !item)
       
    83         return;
       
    84         
       
    85     unsigned index = 0;
       
    86     for (; index < m_entries.size(); ++index) {
       
    87         if (m_entries[index] == item)
       
    88             break;
       
    89     }
       
    90     if (index < m_entries.size()) {
       
    91         m_current = index;
       
    92         if (m_page)
       
    93             m_page->didChangeBackForwardList();
       
    94     }
       
    95 }
       
    96 
       
    97 WebBackForwardListItem* WebBackForwardList::currentItem()
       
    98 {
       
    99     if (m_current != NoCurrentItemIndex)
       
   100         return m_entries[m_current].get();
       
   101     return 0;
       
   102 }
       
   103 
       
   104 WebBackForwardListItem* WebBackForwardList::backItem()
       
   105 {
       
   106     if (m_current && m_current != NoCurrentItemIndex)
       
   107         return m_entries[m_current - 1].get();
       
   108     return 0;
       
   109 }
       
   110 
       
   111 WebBackForwardListItem* WebBackForwardList::forwardItem()
       
   112 {
       
   113     if (m_entries.size() && m_current < m_entries.size() - 1)
       
   114         return m_entries[m_current + 1].get();
       
   115     return 0;
       
   116 }
       
   117 
       
   118 WebBackForwardListItem* WebBackForwardList::itemAtIndex(int index)
       
   119 {
       
   120     // Do range checks without doing math on index to avoid overflow.
       
   121     if (index < -static_cast<int>(m_current))
       
   122         return 0;
       
   123     
       
   124     if (index > forwardListCount())
       
   125         return 0;
       
   126         
       
   127     return m_entries[index + m_current].get();
       
   128 }
       
   129 
       
   130 int WebBackForwardList::backListCount()
       
   131 {
       
   132     return m_current == NoCurrentItemIndex ? 0 : m_current;
       
   133 }
       
   134 
       
   135 int WebBackForwardList::forwardListCount()
       
   136 {
       
   137     return m_current == NoCurrentItemIndex ? 0 : static_cast<int>(m_entries.size()) - (m_current + 1);
       
   138 }
       
   139 
       
   140 BackForwardListItemVector WebBackForwardList::backListWithLimit(unsigned limit)
       
   141 {
       
   142     BackForwardListItemVector list;
       
   143     unsigned size = std::min(backListCount(), static_cast<int>(limit));
       
   144     if (!size)
       
   145         return list;
       
   146 
       
   147     list.resize(size);
       
   148     for (unsigned i = std::max(m_current - limit, 0U), j = 0; i < m_current; ++i, ++j)
       
   149         list[j] = m_entries[i];
       
   150 
       
   151     return list;
       
   152 }
       
   153 
       
   154 BackForwardListItemVector WebBackForwardList::forwardListWithLimit(unsigned limit)
       
   155 {
       
   156     BackForwardListItemVector list;
       
   157     unsigned size = std::min(forwardListCount(), static_cast<int>(limit));
       
   158     if (!size)
       
   159         return list;
       
   160 
       
   161     list.resize(size);
       
   162     unsigned last = std::min(m_current + limit, static_cast<unsigned>(m_entries.size() - 1));
       
   163     for (unsigned i = m_current + 1, j = 0; i <= last; ++i, ++j)
       
   164         list[j] = m_entries[i];
       
   165 
       
   166     return list;
       
   167 }
       
   168 
       
   169 // ImmutableArray::ImmutableArrayCallback [for WebBackForwardListItem] callbacks
       
   170 
       
   171 static void webBackForwardListItemRef(const void* item)
       
   172 {
       
   173     static_cast<WebBackForwardListItem*>(const_cast<void*>(item))->ref();
       
   174 }
       
   175 
       
   176 static void webBackForwardListItemDeref(const void* item)
       
   177 {
       
   178     static_cast<WebBackForwardListItem*>(const_cast<void*>(item))->deref();
       
   179 }
       
   180 
       
   181 PassRefPtr<ImmutableArray> WebBackForwardList::backListAsImmutableArrayWithLimit(unsigned limit)
       
   182 {
       
   183     unsigned size = std::min(backListCount(), static_cast<int>(limit));
       
   184     if (!size)
       
   185         return ImmutableArray::create();
       
   186 
       
   187     void** array = new void*[size];
       
   188     for (unsigned i = std::max<int>(m_current - limit, 0), j = 0; i < m_current; ++i, ++j) {
       
   189         WebBackForwardListItem* item = m_entries[i].get();
       
   190         item->ref();
       
   191         array[j] = item;
       
   192     }
       
   193 
       
   194     ImmutableArray::ImmutableArrayCallbacks callbacks = {
       
   195         webBackForwardListItemRef,
       
   196         webBackForwardListItemDeref
       
   197     };
       
   198     return ImmutableArray::adopt(array, size, &callbacks);
       
   199 }
       
   200 
       
   201 PassRefPtr<ImmutableArray> WebBackForwardList::forwardListAsImmutableArrayWithLimit(unsigned limit)
       
   202 {
       
   203     unsigned size = std::min(forwardListCount(), static_cast<int>(limit));
       
   204     if (!size)
       
   205         return ImmutableArray::create();
       
   206 
       
   207     void** array = new void*[size];
       
   208     unsigned last = std::min(m_current + limit, static_cast<unsigned>(m_entries.size() - 1));
       
   209     for (unsigned i = m_current + 1, j = 0; i <= last; ++i, ++j) {
       
   210         WebBackForwardListItem* item = m_entries[i].get();
       
   211         item->ref();
       
   212         array[j] = item;
       
   213     }
       
   214 
       
   215     ImmutableArray::ImmutableArrayCallbacks callbacks = {
       
   216         webBackForwardListItemRef,
       
   217         webBackForwardListItemDeref
       
   218     };
       
   219     return ImmutableArray::adopt(array, size, &callbacks);
       
   220 }
       
   221 
       
   222 } // namespace WebKit