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
webkit_history_items()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
webkit_history_item_add(WebKitWebHistoryItem * webHistoryItem,WebCore::HistoryItem * historyItem)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
webkit_web_history_item_dispose(GObject * object)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
webkit_web_history_item_finalize(GObject * object)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
webkit_web_history_item_class_init(WebKitWebHistoryItemClass * klass)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
webkit_web_history_item_init(WebKitWebHistoryItem * webHistoryItem)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
webkit_web_history_item_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)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
webkit_web_history_item_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)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 */
webkit_web_history_item_new_with_core_item(PassRefPtr<WebCore::HistoryItem> historyItem)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 */
webkit_web_history_item_new()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 */
webkit_web_history_item_new_with_data(const gchar * uri,const gchar * title)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 */
webkit_web_history_item_get_title(WebKitWebHistoryItem * webHistoryItem)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 */
webkit_web_history_item_get_alternate_title(WebKitWebHistoryItem * webHistoryItem)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 */
webkit_web_history_item_set_alternate_title(WebKitWebHistoryItem * webHistoryItem,const gchar * title)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 */
webkit_web_history_item_get_uri(WebKitWebHistoryItem * webHistoryItem)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 */
webkit_web_history_item_get_original_uri(WebKitWebHistoryItem * webHistoryItem)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 */
webkit_web_history_item_get_last_visited_time(WebKitWebHistoryItem * webHistoryItem)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 */
webkit_web_history_item_copy(WebKitWebHistoryItem * self)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
webkit_web_history_item_get_target(WebKitWebHistoryItem * webHistoryItem)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
webkit_web_history_item_is_target_item(WebKitWebHistoryItem * webHistoryItem)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
webkit_web_history_item_get_children(WebKitWebHistoryItem * webHistoryItem)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
core(WebKitWebHistoryItem * webHistoryItem)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
kit(PassRefPtr<WebCore::HistoryItem> historyItem)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