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