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