Home | History | Annotate | Download | only in webkit
      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