1 /* 2 * Copyright (C) 2008, 2009 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 "webkitwebhistoryitem.h" 23 24 #include "HistoryItem.h" 25 #include "KURL.h" 26 #include "PlatformString.h" 27 #include "webkitglobalsprivate.h" 28 #include "webkitwebhistoryitemprivate.h" 29 #include <glib.h> 30 #include <glib/gi18n-lib.h> 31 #include <wtf/text/CString.h> 32 33 /** 34 * SECTION:webkitwebhistoryitem 35 * @short_description: One item of the #WebKitWebBackForwardList and or global history 36 * @see_also: #WebKitWebBackForwardList 37 * 38 * A history item consists out of a title and a uri. It can be part of the 39 * #WebKitWebBackForwardList and the global history. The global history is used 40 * for coloring the links of visited sites. #WebKitWebHistoryItem's constructed with 41 * #webkit_web_history_item_new and #webkit_web_history_item_new_with_data are 42 * automatically added to the global history. 43 * 44 * <informalexample><programlisting> 45 * /<!-- -->* Inject a visited page into the global history *<!-- -->/ 46 * webkit_web_history_item_new_with_data("http://www.gnome.org/", "GNOME: The Free Software Desktop Project"); 47 * webkit_web_history_item_new_with_data("http://www.webkit.org/", "The WebKit Open Source Project"); 48 * </programlisting></informalexample> 49 * 50 */ 51 52 using namespace WebKit; 53 54 struct _WebKitWebHistoryItemPrivate { 55 WebCore::HistoryItem* historyItem; 56 57 WTF::CString title; 58 WTF::CString alternateTitle; 59 WTF::CString uri; 60 WTF::CString originalUri; 61 62 gboolean disposed; 63 }; 64 65 enum { 66 PROP_0, 67 68 PROP_TITLE, 69 PROP_ALTERNATE_TITLE, 70 PROP_URI, 71 PROP_ORIGINAL_URI, 72 PROP_LAST_VISITED_TIME 73 }; 74 75 G_DEFINE_TYPE(WebKitWebHistoryItem, webkit_web_history_item, G_TYPE_OBJECT); 76 77 static void webkit_web_history_item_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); 78 79 static void webkit_web_history_item_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec); 80 81 GHashTable* webkit_history_items() 82 { 83 static GHashTable* historyItems = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref); 84 return historyItems; 85 } 86 87 void webkit_history_item_add(WebKitWebHistoryItem* webHistoryItem, WebCore::HistoryItem* historyItem) 88 { 89 g_return_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem)); 90 91 GHashTable* table = webkit_history_items(); 92 g_hash_table_insert(table, historyItem, webHistoryItem); 93 } 94 95 static void webkit_web_history_item_dispose(GObject* object) 96 { 97 WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(object); 98 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 99 100 if (!priv->disposed) { 101 WebCore::HistoryItem* item = core(webHistoryItem); 102 item->deref(); 103 priv->disposed = true; 104 } 105 106 G_OBJECT_CLASS(webkit_web_history_item_parent_class)->dispose(object); 107 } 108 109 static void webkit_web_history_item_finalize(GObject* object) 110 { 111 WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(object); 112 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 113 114 priv->title = WTF::CString(); 115 priv->alternateTitle = WTF::CString(); 116 priv->uri = WTF::CString(); 117 priv->originalUri = WTF::CString(); 118 119 G_OBJECT_CLASS(webkit_web_history_item_parent_class)->finalize(object); 120 } 121 122 static void webkit_web_history_item_class_init(WebKitWebHistoryItemClass* klass) 123 { 124 GObjectClass* gobject_class = G_OBJECT_CLASS(klass); 125 126 gobject_class->dispose = webkit_web_history_item_dispose; 127 gobject_class->finalize = webkit_web_history_item_finalize; 128 gobject_class->set_property = webkit_web_history_item_set_property; 129 gobject_class->get_property = webkit_web_history_item_get_property; 130 131 webkitInit(); 132 133 /** 134 * WebKitWebHistoryItem:title: 135 * 136 * The title of the history item. 137 * 138 * Since: 1.0.2 139 */ 140 g_object_class_install_property(gobject_class, 141 PROP_TITLE, 142 g_param_spec_string( 143 "title", 144 _("Title"), 145 _("The title of the history item"), 146 NULL, 147 WEBKIT_PARAM_READABLE)); 148 149 /** 150 * WebKitWebHistoryItem:alternate-title: 151 * 152 * The alternate title of the history item. 153 * 154 * Since: 1.0.2 155 */ 156 g_object_class_install_property(gobject_class, 157 PROP_ALTERNATE_TITLE, 158 g_param_spec_string( 159 "alternate-title", 160 _("Alternate Title"), 161 _("The alternate title of the history item"), 162 NULL, 163 WEBKIT_PARAM_READWRITE)); 164 165 /** 166 * WebKitWebHistoryItem:uri: 167 * 168 * The URI of the history item. 169 * 170 * Since: 1.0.2 171 */ 172 g_object_class_install_property(gobject_class, 173 PROP_URI, 174 g_param_spec_string( 175 "uri", 176 _("URI"), 177 _("The URI of the history item"), 178 NULL, 179 WEBKIT_PARAM_READABLE)); 180 181 /** 182 * WebKitWebHistoryItem:original-uri: 183 * 184 * The original URI of the history item. 185 * 186 * Since: 1.0.2 187 */ 188 g_object_class_install_property(gobject_class, 189 PROP_ORIGINAL_URI, 190 g_param_spec_string( 191 "original-uri", 192 _("Original URI"), 193 _("The original URI of the history item"), 194 NULL, 195 WEBKIT_PARAM_READABLE)); 196 197 /** 198 * WebKitWebHistoryItem:last-visited-time: 199 * 200 * The time at which the history item was last visited. 201 * 202 * Since: 1.0.2 203 */ 204 g_object_class_install_property(gobject_class, 205 PROP_LAST_VISITED_TIME, 206 g_param_spec_double( 207 "last-visited-time", 208 _("Last visited Time"), 209 _("The time at which the history item was last visited"), 210 0, G_MAXDOUBLE, 0, 211 WEBKIT_PARAM_READABLE)); 212 213 g_type_class_add_private(gobject_class, sizeof(WebKitWebHistoryItemPrivate)); 214 } 215 216 static void webkit_web_history_item_init(WebKitWebHistoryItem* webHistoryItem) 217 { 218 webHistoryItem->priv = G_TYPE_INSTANCE_GET_PRIVATE(webHistoryItem, WEBKIT_TYPE_WEB_HISTORY_ITEM, WebKitWebHistoryItemPrivate); 219 } 220 221 static void webkit_web_history_item_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) 222 { 223 WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(object); 224 225 switch(prop_id) { 226 case PROP_ALTERNATE_TITLE: 227 webkit_web_history_item_set_alternate_title(webHistoryItem, g_value_get_string(value)); 228 break; 229 default: 230 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 231 break; 232 } 233 } 234 235 static void webkit_web_history_item_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) 236 { 237 WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(object); 238 239 switch (prop_id) { 240 case PROP_TITLE: 241 g_value_set_string(value, webkit_web_history_item_get_title(webHistoryItem)); 242 break; 243 case PROP_ALTERNATE_TITLE: 244 g_value_set_string(value, webkit_web_history_item_get_alternate_title(webHistoryItem)); 245 break; 246 case PROP_URI: 247 g_value_set_string(value, webkit_web_history_item_get_uri(webHistoryItem)); 248 break; 249 case PROP_ORIGINAL_URI: 250 g_value_set_string(value, webkit_web_history_item_get_original_uri(webHistoryItem)); 251 break; 252 case PROP_LAST_VISITED_TIME: 253 g_value_set_double(value, webkit_web_history_item_get_last_visited_time(webHistoryItem)); 254 break; 255 default: 256 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 257 break; 258 } 259 } 260 261 /* Helper function to create a new WebHistoryItem instance when needed */ 262 WebKitWebHistoryItem* webkit_web_history_item_new_with_core_item(PassRefPtr<WebCore::HistoryItem> historyItem) 263 { 264 return kit(historyItem); 265 } 266 267 268 /** 269 * webkit_web_history_item_new: 270 * 271 * Creates a new #WebKitWebHistoryItem instance 272 * 273 * Return value: the new #WebKitWebHistoryItem 274 */ 275 WebKitWebHistoryItem* webkit_web_history_item_new() 276 { 277 WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); 278 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 279 280 RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); 281 priv->historyItem = item.release().releaseRef(); 282 webkit_history_item_add(webHistoryItem, priv->historyItem); 283 284 return webHistoryItem; 285 } 286 287 /** 288 * webkit_web_history_item_new_with_data: 289 * @uri: the uri of the page 290 * @title: the title of the page 291 * 292 * Creates a new #WebKitWebHistoryItem with the given URI and title 293 * 294 * Return value: the new #WebKitWebHistoryItem 295 */ 296 WebKitWebHistoryItem* webkit_web_history_item_new_with_data(const gchar* uri, const gchar* title) 297 { 298 WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); 299 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 300 301 WebCore::KURL historyUri(WebCore::KURL(), uri); 302 WTF::String historyTitle = WTF::String::fromUTF8(title); 303 RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(historyUri, historyTitle, 0); 304 priv->historyItem = item.release().releaseRef(); 305 webkit_history_item_add(webHistoryItem, priv->historyItem); 306 307 return webHistoryItem; 308 } 309 310 /** 311 * webkit_web_history_item_get_title: 312 * @web_history_item: a #WebKitWebHistoryItem 313 * 314 * Returns: the page title of @web_history_item 315 */ 316 G_CONST_RETURN gchar* webkit_web_history_item_get_title(WebKitWebHistoryItem* webHistoryItem) 317 { 318 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 319 320 WebCore::HistoryItem* item = core(webHistoryItem); 321 322 g_return_val_if_fail(item, NULL); 323 324 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 325 priv->title = item->title().utf8(); 326 327 return priv->title.data(); 328 } 329 330 /** 331 * webkit_web_history_item_get_alternate_title: 332 * @web_history_item: a #WebKitWebHistoryItem 333 * 334 * Returns the alternate title of @web_history_item 335 * 336 * Return value: the alternate title of @web_history_item 337 */ 338 G_CONST_RETURN gchar* webkit_web_history_item_get_alternate_title(WebKitWebHistoryItem* webHistoryItem) 339 { 340 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 341 342 WebCore::HistoryItem* item = core(webHistoryItem); 343 344 g_return_val_if_fail(item, NULL); 345 346 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 347 priv->alternateTitle = item->alternateTitle().utf8(); 348 349 return priv->alternateTitle.data(); 350 } 351 352 /** 353 * webkit_web_history_item_set_alternate_title: 354 * @web_history_item: a #WebKitWebHistoryItem 355 * @title: the alternate title for @this history item 356 * 357 * Sets an alternate title for @web_history_item 358 */ 359 void webkit_web_history_item_set_alternate_title(WebKitWebHistoryItem* webHistoryItem, const gchar* title) 360 { 361 g_return_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem)); 362 g_return_if_fail(title); 363 364 WebCore::HistoryItem* item = core(webHistoryItem); 365 366 item->setAlternateTitle(WTF::String::fromUTF8(title)); 367 g_object_notify(G_OBJECT(webHistoryItem), "alternate-title"); 368 } 369 370 /** 371 * webkit_web_history_item_get_uri: 372 * @web_history_item: a #WebKitWebHistoryItem 373 * 374 * Returns the URI of @this 375 * 376 * Return value: the URI of @web_history_item 377 */ 378 G_CONST_RETURN gchar* webkit_web_history_item_get_uri(WebKitWebHistoryItem* webHistoryItem) 379 { 380 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 381 382 WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); 383 384 g_return_val_if_fail(item, NULL); 385 386 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 387 priv->uri = item->urlString().utf8(); 388 389 return priv->uri.data(); 390 } 391 392 /** 393 * webkit_web_history_item_get_original_uri: 394 * @web_history_item: a #WebKitWebHistoryItem 395 * 396 * Returns the original URI of @web_history_item. 397 * 398 * Return value: the original URI of @web_history_item 399 */ 400 G_CONST_RETURN gchar* webkit_web_history_item_get_original_uri(WebKitWebHistoryItem* webHistoryItem) 401 { 402 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 403 404 WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); 405 406 g_return_val_if_fail(item, NULL); 407 408 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 409 priv->originalUri = item->originalURLString().utf8(); 410 411 return webHistoryItem->priv->originalUri.data(); 412 } 413 414 /** 415 * webkit_web_history_item_get_last_visisted_time : 416 * @web_history_item: a #WebKitWebHistoryItem 417 * 418 * Returns the last time @web_history_item was visited 419 * 420 * Return value: the time in seconds this @web_history_item was last visited 421 */ 422 gdouble webkit_web_history_item_get_last_visited_time(WebKitWebHistoryItem* webHistoryItem) 423 { 424 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), 0); 425 426 WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); 427 428 g_return_val_if_fail(item, 0); 429 430 return item->lastVisitedTime(); 431 } 432 433 /** 434 * webkit_web_history_item_copy: 435 * @web_history_item: a #WebKitWebHistoryItem 436 * 437 * Makes a copy of the item for use with other WebView objects. 438 * 439 * Since: 1.1.18 440 * 441 * Return value: (transfer full): the new #WebKitWebHistoryItem. 442 */ 443 WebKitWebHistoryItem* webkit_web_history_item_copy(WebKitWebHistoryItem* self) 444 { 445 WebKitWebHistoryItemPrivate* selfPrivate = self->priv; 446 447 WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, 0)); 448 WebKitWebHistoryItemPrivate* priv = item->priv; 449 450 priv->title = selfPrivate->title; 451 priv->alternateTitle = selfPrivate->alternateTitle; 452 priv->uri = selfPrivate->uri; 453 priv->originalUri = selfPrivate->originalUri; 454 455 priv->historyItem = selfPrivate->historyItem->copy().releaseRef(); 456 457 return item; 458 } 459 460 /* private methods */ 461 462 G_CONST_RETURN gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem* webHistoryItem) 463 { 464 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 465 466 WebCore::HistoryItem* item = core(webHistoryItem); 467 468 g_return_val_if_fail(item, NULL); 469 470 WTF::CString t = item->target().utf8(); 471 return g_strdup(t.data()); 472 } 473 474 gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem* webHistoryItem) 475 { 476 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), false); 477 478 WebCore::HistoryItem* item = core(webHistoryItem); 479 480 g_return_val_if_fail(item, false); 481 482 return item->isTargetItem(); 483 } 484 485 GList* webkit_web_history_item_get_children(WebKitWebHistoryItem* webHistoryItem) 486 { 487 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 488 489 WebCore::HistoryItem* item = core(webHistoryItem); 490 491 g_return_val_if_fail(item, NULL); 492 493 const WebCore::HistoryItemVector& children = item->children(); 494 if (!children.size()) 495 return NULL; 496 497 unsigned size = children.size(); 498 GList* kids = NULL; 499 for (unsigned i = 0; i < size; ++i) 500 kids = g_list_prepend(kids, kit(children[i].get())); 501 502 return g_list_reverse(kids); 503 } 504 505 WebCore::HistoryItem* WebKit::core(WebKitWebHistoryItem* webHistoryItem) 506 { 507 g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); 508 509 return webHistoryItem->priv->historyItem; 510 } 511 512 WebKitWebHistoryItem* WebKit::kit(PassRefPtr<WebCore::HistoryItem> historyItem) 513 { 514 g_return_val_if_fail(historyItem, NULL); 515 516 RefPtr<WebCore::HistoryItem> item = historyItem; 517 GHashTable* table = webkit_history_items(); 518 WebKitWebHistoryItem* webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, item.get()); 519 520 if (!webHistoryItem) { 521 webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); 522 WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; 523 524 priv->historyItem = item.release().releaseRef(); 525 webkit_history_item_add(webHistoryItem, priv->historyItem); 526 } 527 528 return webHistoryItem; 529 } 530 531