70fdea5da1c0730e0b2dacabd4830fbbf0ff1a4f
[WebKit-https.git] / WebKit / gtk / webkit / webkitwebbackforwardlist.cpp
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
23 #include "webkitwebbackforwardlist.h"
24 #include "webkitprivate.h"
25 #include "webkitwebhistoryitem.h"
26 #include "webkitwebview.h"
27
28 #include <glib.h>
29
30 #include "BackForwardList.h"
31 #include "HistoryItem.h"
32
33 /**
34  * SECTION:webkitwebbackforwardlist
35  * @short_description: The history of a #WebKitWebView
36  * @see_also: #WebKitWebView, #WebKitWebHistoryItem
37  *
38  * <informalexample><programlisting>
39  * /<!-- -->* Get the WebKitWebBackForwardList from the WebKitWebView *<!-- -->/
40  * WebKitWebBackForwardList *back_forward_list = webkit_web_view_get_back_forward_list (my_web_view);
41  * WebKitWebHistoryItem *item = webkit_web_back_forward_list_get_current_item (back_forward_list);
42  *
43  * /<!-- -->* Do something with a WebKitWebHistoryItem *<!-- -->/
44  * g_print("%p", item);
45  *
46  * /<!-- -->* Control some parameters *<!-- -->/
47  * WebKitWebBackForwardList *back_forward_list = webkit_web_view_get_back_forward_list (my_web_view);
48  * webkit_web_back_forward_list_set_limit (back_forward_list, 30);
49  * </programlisting></informalexample>
50  *
51  */
52
53 using namespace WebKit;
54
55 struct _WebKitWebBackForwardListPrivate {
56     WebCore::BackForwardList* backForwardList;
57     gboolean disposed;
58 };
59
60 #define WEBKIT_WEB_BACK_FORWARD_LIST_GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_BACK_FORWARD_LIST, WebKitWebBackForwardListPrivate))
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::BackForwardList* 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     webkit_init();
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 = WEBKIT_WEB_BACK_FORWARD_LIST_GET_PRIVATE(webBackForwardList);
96 }
97
98 /**
99  * webkit_web_back_forward_list_new_with_web_view:
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 WebKitWebBackForwardList* webkit_web_back_forward_list_new_with_web_view(WebKitWebView* webView)
107 {
108     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
109
110     WebKitWebBackForwardList* webBackForwardList;
111
112     webBackForwardList = WEBKIT_WEB_BACK_FORWARD_LIST(g_object_new(WEBKIT_TYPE_WEB_BACK_FORWARD_LIST, NULL));
113     WebKitWebBackForwardListPrivate* priv = webBackForwardList->priv;
114
115     priv->backForwardList = core(webView)->backForwardList();
116     priv->backForwardList->setEnabled(TRUE);
117
118     return webBackForwardList;
119 }
120
121 /**
122  * webkit_web_back_forward_list_go_forward:
123  * @web_back_forward_list: a #WebKitWebBackForwardList
124  *
125  * Steps forward in the back forward list
126  */
127 void webkit_web_back_forward_list_go_forward(WebKitWebBackForwardList* webBackForwardList)
128 {
129     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
130
131     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
132     if (backForwardList->enabled())
133         backForwardList->goForward();
134 }
135
136 /**
137  * webkit_web_back_forward_list_go_back:
138  * @web_back_forward_list: a #WebKitWebBackForwardList
139  *
140  * Steps backward in the back forward list
141  */
142 void webkit_web_back_forward_list_go_back(WebKitWebBackForwardList* webBackForwardList)
143 {
144     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
145
146     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
147     if (backForwardList->enabled())
148         backForwardList->goBack();
149 }
150
151 /**
152  * webkit_web_back_forward_list_contains_item:
153  * @web_back_forward_list: a #WebKitWebBackForwardList
154  * @history_item: the #WebKitWebHistoryItem to check
155  *
156  * Checks if @web_history_item is in the back forward list
157  *
158  * Return: %TRUE if @web_history_item is in the back forward list, %FALSE if it doesn't
159  */
160 gboolean webkit_web_back_forward_list_contains_item(WebKitWebBackForwardList* webBackForwardList, WebKitWebHistoryItem* webHistoryItem)
161 {
162     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), FALSE);
163     g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), FALSE);
164
165     WebCore::HistoryItem* historyItem = core(webHistoryItem);
166
167     g_return_val_if_fail(historyItem != NULL, FALSE);
168
169     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
170
171     return (backForwardList->enabled() ? backForwardList->containsItem(historyItem) : FALSE);
172 }
173
174 /**
175  * webkit_web_back_forward_list_go_to_item:
176  * @web_back_forward_list: a #WebKitWebBackForwardList
177  * @history_item: the #WebKitWebHistoryItem to go to
178  *
179  * Go to the specified @web_history_item in the back forward list
180  */
181 void webkit_web_back_forward_list_go_to_item(WebKitWebBackForwardList* webBackForwardList, WebKitWebHistoryItem* webHistoryItem)
182 {
183     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
184     g_return_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem));
185
186     WebCore::HistoryItem* historyItem = core(webHistoryItem);
187     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
188
189     if (backForwardList->enabled() && historyItem)
190         backForwardList->goToItem(historyItem);
191 }
192
193 /**
194  * webkit_web_back_forward_list_get_forward_list_with_limit:
195  * @web_back_forward_list: a #WebKitWebBackForwardList
196  * @limit: the number of items to retrieve
197  *
198  * Returns a list of items that succeed the current item, limited by @limit
199  *
200  * Return value: a #GList of items succeeding the current item, limited by @limit
201  */
202 GList* webkit_web_back_forward_list_get_forward_list_with_limit(WebKitWebBackForwardList* webBackForwardList, gint limit)
203 {
204     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
205
206     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
207     if (!backForwardList || !backForwardList->enabled())
208         return NULL;
209
210     WebCore::HistoryItemVector items;
211     GList* forwardItems = { 0 };
212
213     backForwardList->forwardListWithLimit(limit, items);
214
215     for (unsigned i = 0; i < items.size(); i++) {
216         WebKitWebHistoryItem* webHistoryItem = kit(items[i]);
217         forwardItems = g_list_prepend(forwardItems, webHistoryItem);
218     }
219
220     return forwardItems;
221 }
222
223 /**
224  * webkit_web_back_forward_list_get_back_list_with_limit:
225  * @web_back_forward_list: a #WebKitWebBackForwardList
226  * @limit: the number of items to retrieve
227  *
228  * Returns a list of items that precede the current item, limited by @limit
229  *
230  * Return value: a #GList of items preceding the current item, limited by @limit
231  */
232 GList* webkit_web_back_forward_list_get_back_list_with_limit(WebKitWebBackForwardList* webBackForwardList, gint limit)
233 {
234     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
235
236     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
237     if (!backForwardList || !backForwardList->enabled())
238         return NULL;
239
240     WebCore::HistoryItemVector items;
241     GList* backItems = { 0 };
242
243     backForwardList->backListWithLimit(limit, items);
244
245     for (unsigned i = 0; i < items.size(); i++) {
246         WebKitWebHistoryItem* webHistoryItem = kit(items[i]);
247         backItems = g_list_prepend(backItems, webHistoryItem);
248     }
249
250     return backItems;
251 }
252
253 /**
254  * webkit_web_back_forward_list_get_back_item:
255  * @web_back_forward_list: a #WebKitWebBackForwardList
256  *
257  * Returns the item that precedes the current item
258  *
259  * Return value: the #WebKitWebHistoryItem preceding the current item
260  */
261 WebKitWebHistoryItem* webkit_web_back_forward_list_get_back_item(WebKitWebBackForwardList* webBackForwardList)
262 {
263     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
264
265     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
266     if (!backForwardList || !backForwardList->enabled())
267         return NULL;
268
269     WebCore::HistoryItem* historyItem = backForwardList->backItem();
270
271     return (historyItem ? kit(historyItem) : NULL);
272 }
273
274 /**
275  * webkit_web_back_forward_list_get_current_item:
276  * @web_back_forward_list: a #WebKitWebBackForwardList
277  *
278  * Returns the current item.
279  *
280  * Returns a NULL value if the back forward list is empty
281  *
282  * Return value: a #WebKitWebHistoryItem
283  */
284 WebKitWebHistoryItem* webkit_web_back_forward_list_get_current_item(WebKitWebBackForwardList* webBackForwardList)
285 {
286     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
287
288     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
289     if (!backForwardList || !backForwardList->enabled())
290         return NULL;
291
292     WebCore::HistoryItem* historyItem = backForwardList->currentItem();
293
294     return (historyItem ? kit(historyItem) : NULL);
295 }
296
297 /**
298  * webkit_web_back_forward_list_get_forward_item:
299  * @web_back_forward_list: a #WebKitWebBackForwardList
300  *
301  * Returns the item that succeeds the current item.
302  *
303  * Returns a NULL value if there nothing that succeeds the current item
304  *
305  * Return value: a #WebKitWebHistoryItem
306  */
307 WebKitWebHistoryItem* webkit_web_back_forward_list_get_forward_item(WebKitWebBackForwardList* webBackForwardList)
308 {
309     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
310
311     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
312     if (!backForwardList || !backForwardList->enabled())
313         return NULL;
314
315     WebCore::HistoryItem* historyItem = backForwardList->forwardItem();
316
317     return (historyItem ? kit(historyItem) : NULL);
318 }
319
320 /**
321  * webkit_web_back_forward_list_get_nth_item:
322  * @web_back_forward_list: a #WebKitWebBackForwardList
323  * @index: the index of the item
324  *
325  * Returns the item at a given index relative to the current item.
326  *
327  * Return value: the #WebKitWebHistoryItem located at the specified index relative to the current item
328  */
329 WebKitWebHistoryItem* webkit_web_back_forward_list_get_nth_item(WebKitWebBackForwardList* webBackForwardList, gint index)
330 {
331     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
332
333     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
334     if (!backForwardList)
335         return NULL;
336
337     WebCore::HistoryItem* historyItem = backForwardList->itemAtIndex(index);
338
339     return (historyItem ? kit(historyItem) : NULL);
340 }
341
342 /**
343  * webkit_web_back_forward_list_get_back_length:
344  * @web_back_forward_list: a #WebKitWebBackForwardList
345  *
346  * Returns the number of items that preced the current item.
347  *
348  * Return value: a #gint corresponding to the number of items preceding the current item
349  */
350 gint webkit_web_back_forward_list_get_back_length(WebKitWebBackForwardList* webBackForwardList)
351 {
352     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), 0);
353
354     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
355     if (!backForwardList || !backForwardList->enabled())
356         return 0;
357
358     return backForwardList->backListCount();
359 }
360
361 /**
362  * webkit_web_back_forward_list_get_forward_length:
363  * @web_back_forward_list: a #WebKitWebBackForwardList
364  *
365  * Returns the number of items that succeed the current item.
366  *
367  * Return value: a #gint corresponding to the nuber of items succeeding the current item
368  */
369 gint webkit_web_back_forward_list_get_forward_length(WebKitWebBackForwardList* webBackForwardList)
370 {
371     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), 0);
372
373     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
374     if (!backForwardList || !backForwardList->enabled())
375         return 0;
376
377     return backForwardList->forwardListCount();
378 }
379
380 /**
381  * webkit_web_back_forward_list_get_limit:
382  * @web_back_forward_list: a #WebKitWebBackForwardList
383  *
384  * Returns the maximum limit of the back forward list.
385  *
386  * Return value: a #gint indicating the number of #WebKitWebHistoryItem the back forward list can hold
387  */
388 gint webkit_web_back_forward_list_get_limit(WebKitWebBackForwardList* webBackForwardList)
389 {
390     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), 0);
391
392     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
393     if (!backForwardList || !backForwardList->enabled())
394         return 0;
395
396     return backForwardList->capacity();
397 }
398
399 /**
400  * webkit_web_back_forward_list_set_limit:
401  * @web_back_forward_list: a #WebKitWebBackForwardList
402  * @limit: the limit to set the back forward list to
403  *
404  * Sets the maximum limit of the back forward list. If the back forward list
405  * exceeds its capacity, items will be removed everytime a new item has been
406  * added.
407  */
408 void webkit_web_back_forward_list_set_limit(WebKitWebBackForwardList* webBackForwardList, gint limit)
409 {
410     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
411
412     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
413     if (backForwardList)
414         backForwardList->setCapacity(limit);
415 }
416
417 /**
418  * webkit_web_back_forward_list_add_item:
419  * @web_back_forward_list: a #WebKitWebBackForwardList
420  * @history_item: the #WebKitWebHistoryItem to add
421  *
422  * Adds the item to the #WebKitWebBackForwardList.
423  *
424  * The @webBackForwardList will add a reference to the @webHistoryItem, so you
425  * don't need to keep a reference once you've added it to the list.
426  *
427  * Since: 1.1.1
428  */
429 void webkit_web_back_forward_list_add_item(WebKitWebBackForwardList *webBackForwardList, WebKitWebHistoryItem *webHistoryItem)
430 {
431     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
432
433     g_object_ref(webHistoryItem);
434
435     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
436     WebCore::HistoryItem* historyItem = core(webHistoryItem);
437
438     backForwardList->addItem(historyItem);
439 }
440
441 /**
442  * webkit_web_back_forward_list_clear:
443  * @webBackForwardList:  a #WebKitWebBackForwardList
444  *
445  * Clears the @webBackForwardList by removing all its elements. Note that not even
446  * the current page is kept in list when cleared so you would have to add it later.
447  *
448  * Since: 1.3.1
449  **/
450 void webkit_web_back_forward_list_clear(WebKitWebBackForwardList* webBackForwardList)
451 {
452     g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList));
453
454     WebCore::BackForwardList* backForwardList = core(webBackForwardList);
455     if (!backForwardList || !backForwardList->enabled() || !backForwardList->entries().size())
456         return;
457
458     // Clear the current list by setting capacity to 0
459     int capacity = backForwardList->capacity();
460     backForwardList->setCapacity(0);
461     backForwardList->setCapacity(capacity);
462 }
463
464 WebCore::BackForwardList* WebKit::core(WebKitWebBackForwardList* webBackForwardList)
465 {
466     g_return_val_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList), NULL);
467
468     return webBackForwardList->priv ? webBackForwardList->priv->backForwardList : 0;
469 }