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