Home | History | Annotate | Download | only in webkit
      1 /*
      2  * Copyright (C) 2008 Jan Michael C. Alonzo
      3  * Copyright (C) 2009 Igalia S.L.
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  */
     20 
     21 #include "config.h"
     22 #include "webkitwebbackforwardlist.h"
     23 
     24 #include "BackForwardListImpl.h"
     25 #include "HistoryItem.h"
     26 #include "Page.h"
     27 #include "webkitglobalsprivate.h"
     28 #include "webkitwebbackforwardlistprivate.h"
     29 #include "webkitwebhistoryitem.h"
     30 #include "webkitwebhistoryitemprivate.h"
     31 #include "webkitwebview.h"
     32 #include "webkitwebviewprivate.h"
     33 #include <glib.h>
     34 
     35 /**
     36  * SECTION:webkitwebbackforwardlist
     37  * @short_description: The history of a #WebKitWebView
     38  * @see_also: #WebKitWebView, #WebKitWebHistoryItem
     39  *
     40  * <informalexample><programlisting>
     41  * /<!-- -->* Get the WebKitWebBackForwardList from the WebKitWebView *<!-- -->/
     42  * WebKitWebBackForwardList *back_forward_list = webkit_web_view_get_back_forward_list (my_web_view);
     43  * WebKitWebHistoryItem *item = webkit_web_back_forward_list_get_current_item (back_forward_list);
     44  *
     45  * /<!-- -->* Do something with a WebKitWebHistoryItem *<!-- -->/
     46  * g_print("%p", item);
     47  *
     48  * /<!-- -->* Control some parameters *<!-- -->/
     49  * WebKitWebBackForwardList *back_forward_list = webkit_web_view_get_back_forward_list (my_web_view);
     50  * webkit_web_back_forward_list_set_limit (back_forward_list, 30);
     51  * </programlisting></informalexample>
     52  *
     53  */
     54 
     55 using namespace WebKit;
     56 
     57 struct _WebKitWebBackForwardListPrivate {
     58     WebCore::BackForwardListImpl* backForwardList;
     59     gboolean disposed;
     60 };
     61 
     62 G_DEFINE_TYPE(WebKitWebBackForwardList, webkit_web_back_forward_list, G_TYPE_OBJECT);
     63 
     64 static void webkit_web_back_forward_list_dispose(GObject* object)
     65 {
     66     WebKitWebBackForwardList* list = WEBKIT_WEB_BACK_FORWARD_LIST(object);
     67     WebCore::BackForwardListImpl* backForwardList = core(list);
     68     WebKitWebBackForwardListPrivate* priv = list->priv;
     69 
     70     if (!priv->disposed) {
     71         priv->disposed = true;
     72 
     73         WebCore::HistoryItemVector items = backForwardList->entries();
     74         GHashTable* table = webkit_history_items();
     75         for (unsigned i = 0; i < items.size(); i++)
     76             g_hash_table_remove(table, items[i].get());
     77     }
     78 
     79     G_OBJECT_CLASS(webkit_web_back_forward_list_parent_class)->dispose(object);
     80 }
     81 
     82 static void webkit_web_back_forward_list_class_init(WebKitWebBackForwardListClass* klass)
     83 {
     84     GObjectClass* object_class = G_OBJECT_CLASS(klass);
     85 
     86     object_class->dispose = webkit_web_back_forward_list_dispose;
     87 
     88     webkitInit();
     89 
     90     g_type_class_add_private(klass, sizeof(WebKitWebBackForwardListPrivate));
     91 }
     92 
     93 static void webkit_web_back_forward_list_init(WebKitWebBackForwardList* webBackForwardList)
     94 {
     95     webBackForwardList->priv = G_TYPE_INSTANCE_GET_PRIVATE(webBackForwardList, WEBKIT_TYPE_WEB_BACK_FORWARD_LIST, WebKitWebBackForwardListPrivate);
     96 }
     97 
     98 /**
     99  * webkit_web_back_forward_list_new_with_web_view: (skip)
    100  * @web_view: the back forward list's #WebKitWebView
    101  *
    102  * Creates an instance of the back forward list with a controlling #WebKitWebView
    103  *
    104  * Return value: a #WebKitWebBackForwardList
    105  *
    106  * Deprecated: 1.3.4: Instances of #WebKitWebBackForwardList are
    107  * created and owned by #WebKitWebView instances only.
    108  */
    109 WebKitWebBackForwardList* webkit_web_back_forward_list_new_with_web_view(WebKitWebView* webView)
    110 {
    111     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
    112 
    113     WebKitWebBackForwardList* webBackForwardList;
    114 
    115     webBackForwardList = WEBKIT_WEB_BACK_FORWARD_LIST(g_object_new(WEBKIT_TYPE_WEB_BACK_FORWARD_LIST, NULL));
    116     WebKitWebBackForwardListPrivate* priv = webBackForwardList->priv;
    117 
    118     priv->backForwardList = static_cast<WebCore::BackForwardListImpl*>(core(webView)->backForwardList());
    119     priv->backForwardList->setEnabled(TRUE);
    120 
    121     return webBackForwardList;
    122 }
    123 
    124 /**
    125  * webkit_web_back_forward_list_go_forward:
    126  * @web_back_forward_list: a #WebKitWebBackForwardList
    127  *
    128  * Steps forward in the back forward list
    129  */
    130 void webkit_web_back_forward_list_go_forward(WebKitWebBackForwardList* webBackForwardList)
    131 {
    132     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
    133 
    134     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    135     if (backForwardList->enabled())
    136         backForwardList->goForward();
    137 }
    138 
    139 /**
    140  * webkit_web_back_forward_list_go_back:
    141  * @web_back_forward_list: a #WebKitWebBackForwardList
    142  *
    143  * Steps backward in the back forward list
    144  */
    145 void webkit_web_back_forward_list_go_back(WebKitWebBackForwardList* webBackForwardList)
    146 {
    147     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
    148 
    149     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    150     if (backForwardList->enabled())
    151         backForwardList->goBack();
    152 }
    153 
    154 /**
    155  * webkit_web_back_forward_list_contains_item:
    156  * @web_back_forward_list: a #WebKitWebBackForwardList
    157  * @history_item: (type WebKit.WebHistoryItem) (transfer none): the #WebKitWebHistoryItem to check
    158  *
    159  * Checks if @web_history_item is in the back forward list
    160  *
    161  * Return value: %TRUE if @web_history_item is in the back forward list, %FALSE if it doesn't
    162  */
    163 gboolean webkit_web_back_forward_list_contains_item(WebKitWebBackForwardList* webBackForwardList, WebKitWebHistoryItem* webHistoryItem)
    164 {
    165     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), FALSE);
    166     g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), FALSE);
    167 
    168     WebCore::HistoryItem* historyItem = core(webHistoryItem);
    169 
    170     g_return_val_if_fail(historyItem != NULL, FALSE);
    171 
    172     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    173 
    174     return (backForwardList->enabled() ? backForwardList->containsItem(historyItem) : FALSE);
    175 }
    176 
    177 /**
    178  * webkit_web_back_forward_list_go_to_item:
    179  * @web_back_forward_list: a #WebKitWebBackForwardList
    180  * @history_item: (type WebKit.WebHistoryItem) (transfer none): the #WebKitWebHistoryItem to go to
    181  *
    182  * Go to the specified @web_history_item in the back forward list
    183  */
    184 void webkit_web_back_forward_list_go_to_item(WebKitWebBackForwardList* webBackForwardList, WebKitWebHistoryItem* webHistoryItem)
    185 {
    186     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
    187     g_return_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem));
    188 
    189     WebCore::HistoryItem* historyItem = core(webHistoryItem);
    190     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    191 
    192     if (backForwardList->enabled() && historyItem)
    193         backForwardList->goToItem(historyItem);
    194 }
    195 
    196 /**
    197  * webkit_web_back_forward_list_get_forward_list_with_limit:
    198  * @web_back_forward_list: a #WebKitWebBackForwardList
    199  * @limit: the number of items to retrieve
    200  *
    201  * Returns a list of items that succeed the current item, limited by @limit
    202  *
    203  * Return value: (element-type WebKit.WebHistoryItem) (transfer container): a #GList of items succeeding the current item, limited by @limit
    204  */
    205 GList* webkit_web_back_forward_list_get_forward_list_with_limit(WebKitWebBackForwardList* webBackForwardList, gint limit)
    206 {
    207     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    208 
    209     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    210     if (!backForwardList || !backForwardList->enabled())
    211         return NULL;
    212 
    213     WebCore::HistoryItemVector items;
    214     GList* forwardItems = { 0 };
    215 
    216     backForwardList->forwardListWithLimit(limit, items);
    217 
    218     for (unsigned i = 0; i < items.size(); i++) {
    219         WebKitWebHistoryItem* webHistoryItem = kit(items[i]);
    220         forwardItems = g_list_prepend(forwardItems, webHistoryItem);
    221     }
    222 
    223     return forwardItems;
    224 }
    225 
    226 /**
    227  * webkit_web_back_forward_list_get_back_list_with_limit:
    228  * @web_back_forward_list: a #WebKitWebBackForwardList
    229  * @limit: the number of items to retrieve
    230  *
    231  * Returns a list of items that precede the current item, limited by @limit
    232  *
    233  * Return value: (element-type WebKit.WebHistoryItem) (transfer container): a #GList of items preceding the current item, limited by @limit
    234  */
    235 GList* webkit_web_back_forward_list_get_back_list_with_limit(WebKitWebBackForwardList* webBackForwardList, gint limit)
    236 {
    237     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    238 
    239     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    240     if (!backForwardList || !backForwardList->enabled())
    241         return NULL;
    242 
    243     WebCore::HistoryItemVector items;
    244     GList* backItems = { 0 };
    245 
    246     backForwardList->backListWithLimit(limit, items);
    247 
    248     for (unsigned i = 0; i < items.size(); i++) {
    249         WebKitWebHistoryItem* webHistoryItem = kit(items[i]);
    250         backItems = g_list_prepend(backItems, webHistoryItem);
    251     }
    252 
    253     return backItems;
    254 }
    255 
    256 /**
    257  * webkit_web_back_forward_list_get_back_item:
    258  * @web_back_forward_list: a #WebKitWebBackForwardList
    259  *
    260  * Returns the item that precedes the current item
    261  *
    262  * Return value: (type WebKit.WebHistoryItem) (transfer none): the #WebKitWebHistoryItem preceding the current item
    263  */
    264 WebKitWebHistoryItem* webkit_web_back_forward_list_get_back_item(WebKitWebBackForwardList* webBackForwardList)
    265 {
    266     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    267 
    268     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    269     if (!backForwardList || !backForwardList->enabled())
    270         return NULL;
    271 
    272     WebCore::HistoryItem* historyItem = backForwardList->backItem();
    273 
    274     return (historyItem ? kit(historyItem) : NULL);
    275 }
    276 
    277 /**
    278  * webkit_web_back_forward_list_get_current_item:
    279  * @web_back_forward_list: a #WebKitWebBackForwardList
    280  *
    281  * Returns the current item.
    282  *
    283  * Returns a NULL value if the back forward list is empty
    284  *
    285  * Return value: (type WebKit.WebHistoryItem) (transfer none): a #WebKitWebHistoryItem
    286  */
    287 WebKitWebHistoryItem* webkit_web_back_forward_list_get_current_item(WebKitWebBackForwardList* webBackForwardList)
    288 {
    289     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    290 
    291     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    292     if (!backForwardList || !backForwardList->enabled())
    293         return NULL;
    294 
    295     WebCore::HistoryItem* historyItem = backForwardList->currentItem();
    296 
    297     return (historyItem ? kit(historyItem) : NULL);
    298 }
    299 
    300 /**
    301  * webkit_web_back_forward_list_get_forward_item:
    302  * @web_back_forward_list: a #WebKitWebBackForwardList
    303  *
    304  * Returns the item that succeeds the current item.
    305  *
    306  * Returns a NULL value if there nothing that succeeds the current item
    307  *
    308  * Return value: (type WebKit.WebHistoryItem) (transfer none): a #WebKitWebHistoryItem
    309  */
    310 WebKitWebHistoryItem* webkit_web_back_forward_list_get_forward_item(WebKitWebBackForwardList* webBackForwardList)
    311 {
    312     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    313 
    314     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    315     if (!backForwardList || !backForwardList->enabled())
    316         return NULL;
    317 
    318     WebCore::HistoryItem* historyItem = backForwardList->forwardItem();
    319 
    320     return (historyItem ? kit(historyItem) : NULL);
    321 }
    322 
    323 /**
    324  * webkit_web_back_forward_list_get_nth_item:
    325  * @web_back_forward_list: a #WebKitWebBackForwardList
    326  * @index: the index of the item
    327  *
    328  * Returns the item at a given index relative to the current item.
    329  *
    330  * Return value: (type WebKit.WebHistoryItem) (transfer none): the #WebKitWebHistoryItem located at the specified index relative to the current item
    331  */
    332 WebKitWebHistoryItem* webkit_web_back_forward_list_get_nth_item(WebKitWebBackForwardList* webBackForwardList, gint index)
    333 {
    334     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    335 
    336     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    337     if (!backForwardList)
    338         return NULL;
    339 
    340     WebCore::HistoryItem* historyItem = backForwardList->itemAtIndex(index);
    341 
    342     return (historyItem ? kit(historyItem) : NULL);
    343 }
    344 
    345 /**
    346  * webkit_web_back_forward_list_get_back_length:
    347  * @web_back_forward_list: a #WebKitWebBackForwardList
    348  *
    349  * Returns the number of items that preced the current item.
    350  *
    351  * Return value: a #gint corresponding to the number of items preceding the current item
    352  */
    353 gint webkit_web_back_forward_list_get_back_length(WebKitWebBackForwardList* webBackForwardList)
    354 {
    355     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), 0);
    356 
    357     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    358     if (!backForwardList || !backForwardList->enabled())
    359         return 0;
    360 
    361     return backForwardList->backListCount();
    362 }
    363 
    364 /**
    365  * webkit_web_back_forward_list_get_forward_length:
    366  * @web_back_forward_list: a #WebKitWebBackForwardList
    367  *
    368  * Returns the number of items that succeed the current item.
    369  *
    370  * Return value: a #gint corresponding to the nuber of items succeeding the current item
    371  */
    372 gint webkit_web_back_forward_list_get_forward_length(WebKitWebBackForwardList* webBackForwardList)
    373 {
    374     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), 0);
    375 
    376     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    377     if (!backForwardList || !backForwardList->enabled())
    378         return 0;
    379 
    380     return backForwardList->forwardListCount();
    381 }
    382 
    383 /**
    384  * webkit_web_back_forward_list_get_limit:
    385  * @web_back_forward_list: a #WebKitWebBackForwardList
    386  *
    387  * Returns the maximum limit of the back forward list.
    388  *
    389  * Return value: a #gint indicating the number of #WebKitWebHistoryItem the back forward list can hold
    390  */
    391 gint webkit_web_back_forward_list_get_limit(WebKitWebBackForwardList* webBackForwardList)
    392 {
    393     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), 0);
    394 
    395     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    396     if (!backForwardList || !backForwardList->enabled())
    397         return 0;
    398 
    399     return backForwardList->capacity();
    400 }
    401 
    402 /**
    403  * webkit_web_back_forward_list_set_limit:
    404  * @web_back_forward_list: a #WebKitWebBackForwardList
    405  * @limit: the limit to set the back forward list to
    406  *
    407  * Sets the maximum limit of the back forward list. If the back forward list
    408  * exceeds its capacity, items will be removed everytime a new item has been
    409  * added.
    410  */
    411 void webkit_web_back_forward_list_set_limit(WebKitWebBackForwardList* webBackForwardList, gint limit)
    412 {
    413     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
    414 
    415     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    416     if (backForwardList)
    417         backForwardList->setCapacity(limit);
    418 }
    419 
    420 /**
    421  * webkit_web_back_forward_list_add_item:
    422  * @web_back_forward_list: a #WebKitWebBackForwardList
    423  * @history_item: (type WebKit.WebHistoryItem) (transfer none): the #WebKitWebHistoryItem to add
    424  *
    425  * Adds the item to the #WebKitWebBackForwardList.
    426  *
    427  * The @webBackForwardList will add a reference to the @webHistoryItem, so you
    428  * don't need to keep a reference once you've added it to the list.
    429  *
    430  * Since: 1.1.1
    431  */
    432 void webkit_web_back_forward_list_add_item(WebKitWebBackForwardList *webBackForwardList, WebKitWebHistoryItem *webHistoryItem)
    433 {
    434     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
    435 
    436     g_object_ref(webHistoryItem);
    437 
    438     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    439     WebCore::HistoryItem* historyItem = core(webHistoryItem);
    440 
    441     backForwardList->addItem(historyItem);
    442 }
    443 
    444 /**
    445  * webkit_web_back_forward_list_clear:
    446  * @web_back_forward_list: the #WebKitWebBackForwardList to be cleared
    447  *
    448  * Clears the @webBackForwardList by removing all its elements. Note that not even
    449  * the current page is kept in list when cleared so you would have to add it later.
    450  *
    451  * Since: 1.3.1
    452  **/
    453 void webkit_web_back_forward_list_clear(WebKitWebBackForwardList* webBackForwardList)
    454 {
    455     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
    456 
    457     WebCore::BackForwardListImpl* backForwardList = core(webBackForwardList);
    458     if (!backForwardList || !backForwardList->enabled() || !backForwardList->entries().size())
    459         return;
    460 
    461     // Clear the current list by setting capacity to 0
    462     int capacity = backForwardList->capacity();
    463     backForwardList->setCapacity(0);
    464     backForwardList->setCapacity(capacity);
    465 }
    466 
    467 WebCore::BackForwardListImpl* WebKit::core(WebKitWebBackForwardList* webBackForwardList)
    468 {
    469     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
    470 
    471     return webBackForwardList->priv ? webBackForwardList->priv->backForwardList : 0;
    472 }
    473