• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 Christian Dywan <christian@lanedo.com>
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 #include "config.h"
21 #include "webkiticondatabase.h"
22 
23 #include "DatabaseDetails.h"
24 #include "DatabaseTracker.h"
25 #include "FileSystem.h"
26 #include "IconDatabase.h"
27 #include "Image.h"
28 #include "IntSize.h"
29 #include "webkitglobalsprivate.h"
30 #include "webkitmarshal.h"
31 #include "webkitsecurityoriginprivate.h"
32 #include "webkitwebframe.h"
33 #include <glib/gi18n-lib.h>
34 #include <wtf/gobject/GOwnPtr.h>
35 #include <wtf/text/CString.h>
36 
37 /**
38  * SECTION:webkitwebdatabase
39  * @short_description: A WebKit web application database
40  *
41  * #WebKitIconDatabase provides access to website icons, as shown
42  * in tab labels, window captions or bookmarks. All views share
43  * the same icon database.
44  *
45  * The icon database is enabled by default and stored in
46  * ~/.local/share/webkit/icondatabase, depending on XDG_DATA_HOME.
47  *
48  * WebKit will automatically look for available icons in link elements
49  * on opened pages as well as an existing favicon.ico and load the
50  * images found into the memory cache if possible. The signal "icon-loaded"
51  * will be emitted when any icon is found and loaded.
52  * Old Icons are automatically cleaned up after 4 days.
53  *
54  * webkit_icon_database_set_path() can be used to change the location
55  * of the database and also to disable it by passing %NULL.
56  *
57  * If WebKitWebSettings::enable-private-browsing is %TRUE new icons
58  * won't be added to the database on disk and no existing icons will
59  * be deleted from it.
60  *
61  * Since: 1.3.13
62  */
63 
64 using namespace WebKit;
65 
66 enum {
67     PROP_0,
68 
69     PROP_PATH,
70 };
71 
72 enum {
73     ICON_LOADED,
74 
75     LAST_SIGNAL
76 };
77 
78 static guint webkit_icon_database_signals[LAST_SIGNAL] = { 0, };
79 
80 G_DEFINE_TYPE(WebKitIconDatabase, webkit_icon_database, G_TYPE_OBJECT);
81 
82 struct _WebKitIconDatabasePrivate {
83     GOwnPtr<gchar> path;
84 };
85 
webkit_icon_database_finalize(GObject * object)86 static void webkit_icon_database_finalize(GObject* object)
87 {
88     // Call C++ destructors, the reverse of 'placement new syntax'
89     WEBKIT_ICON_DATABASE(object)->priv->~WebKitIconDatabasePrivate();
90 
91     G_OBJECT_CLASS(webkit_icon_database_parent_class)->finalize(object);
92 }
93 
webkit_icon_database_dispose(GObject * object)94 static void webkit_icon_database_dispose(GObject* object)
95 {
96     G_OBJECT_CLASS(webkit_icon_database_parent_class)->dispose(object);
97 }
98 
webkit_icon_database_set_property(GObject * object,guint propId,const GValue * value,GParamSpec * pspec)99 static void webkit_icon_database_set_property(GObject* object, guint propId, const GValue* value, GParamSpec* pspec)
100 {
101     WebKitIconDatabase* database = WEBKIT_ICON_DATABASE(object);
102 
103     switch (propId) {
104     case PROP_PATH:
105         webkit_icon_database_set_path(database, g_value_get_string(value));
106         break;
107     default:
108         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
109         break;
110     }
111 }
112 
webkit_icon_database_get_property(GObject * object,guint propId,GValue * value,GParamSpec * pspec)113 static void webkit_icon_database_get_property(GObject* object, guint propId, GValue* value, GParamSpec* pspec)
114 {
115     WebKitIconDatabase* database = WEBKIT_ICON_DATABASE(object);
116 
117     switch (propId) {
118     case PROP_PATH:
119         g_value_set_string(value, webkit_icon_database_get_path(database));
120         break;
121     default:
122         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
123         break;
124     }
125 }
126 
webkit_icon_database_class_init(WebKitIconDatabaseClass * klass)127 static void webkit_icon_database_class_init(WebKitIconDatabaseClass* klass)
128 {
129     webkitInit();
130 
131     GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
132     gobjectClass->dispose = webkit_icon_database_dispose;
133     gobjectClass->finalize = webkit_icon_database_finalize;
134     gobjectClass->set_property = webkit_icon_database_set_property;
135     gobjectClass->get_property = webkit_icon_database_get_property;
136 
137      /**
138       * WebKitIconDatabase:path:
139       *
140       * The absolute path of the icon database folder.
141       *
142       * Since: 1.3.13
143       */
144      g_object_class_install_property(gobjectClass, PROP_PATH,
145                                      g_param_spec_string("path",
146                                                          _("Path"),
147                                                          _("The absolute path of the icon database folder"),
148                                                          NULL,
149                 WEBKIT_PARAM_READWRITE));
150 
151     /**
152      * WebKitIconDatabase::icon-loaded:
153      * @database: the object on which the signal is emitted
154      * @frame: the frame containing the icon
155      * @frame_uri: the URI of the frame containing the icon
156      *
157      * This signal is emitted when a favicon is available for a page,
158      * or a child frame.
159      * See WebKitWebView::icon-loaded if you only need the favicon for
160      * the main frame of a particular #WebKitWebView.
161      *
162      * Since: 1.3.13
163      */
164     webkit_icon_database_signals[ICON_LOADED] = g_signal_new("icon-loaded",
165             G_TYPE_FROM_CLASS(klass),
166             (GSignalFlags)G_SIGNAL_RUN_LAST,
167             0,
168             NULL,
169             NULL,
170             webkit_marshal_VOID__OBJECT_STRING,
171             G_TYPE_NONE, 2,
172             WEBKIT_TYPE_WEB_FRAME,
173             G_TYPE_STRING);
174 
175     g_type_class_add_private(klass, sizeof(WebKitIconDatabasePrivate));
176 }
177 
webkit_icon_database_init(WebKitIconDatabase * database)178 static void webkit_icon_database_init(WebKitIconDatabase* database)
179 {
180     database->priv = G_TYPE_INSTANCE_GET_PRIVATE(database, WEBKIT_TYPE_ICON_DATABASE, WebKitIconDatabasePrivate);
181     // 'placement new syntax', see webkitwebview.cpp
182     new (database->priv) WebKitIconDatabasePrivate();
183 }
184 
185 /**
186  * webkit_icon_database_get_path:
187  * @database: a #WebKitIconDatabase
188  *
189  * Determines the absolute path to the database folder on disk.
190  *
191  * Returns: the absolute path of the database folder, or %NULL
192  *
193  * Since: 1.3.13
194  **/
webkit_icon_database_get_path(WebKitIconDatabase * database)195 G_CONST_RETURN gchar* webkit_icon_database_get_path(WebKitIconDatabase* database)
196 {
197     g_return_val_if_fail(WEBKIT_IS_ICON_DATABASE(database), 0);
198 
199     return database->priv->path.get();
200 }
201 
closeIconDatabaseOnExit()202 static void closeIconDatabaseOnExit()
203 {
204     if (WebCore::iconDatabase().isEnabled()) {
205         WebCore::iconDatabase().setEnabled(false);
206         WebCore::iconDatabase().close();
207     }
208 }
209 
210 /**
211  * webkit_icon_database_set_path:
212  * @database: a #WebKitIconDatabase
213  * @path: an absolute path to the icon database folder
214  *
215  * Specifies the absolute path to the database folder on disk.
216  *
217  * Passing %NULL or "" disables the icon database.
218  *
219  * Since: 1.3.13
220  **/
webkit_icon_database_set_path(WebKitIconDatabase * database,const gchar * path)221 void webkit_icon_database_set_path(WebKitIconDatabase* database, const gchar* path)
222 {
223     g_return_if_fail(WEBKIT_IS_ICON_DATABASE(database));
224 
225     if (database->priv->path.get())
226         WebCore::iconDatabase().close();
227 
228     if (!(path && path[0])) {
229         database->priv->path.set(0);
230         WebCore::iconDatabase().setEnabled(false);
231         return;
232     }
233 
234     database->priv->path.set(g_strdup(path));
235 
236     WebCore::iconDatabase().setEnabled(true);
237     WebCore::iconDatabase().open(WebCore::filenameToString(database->priv->path.get()), WebCore::IconDatabase::defaultDatabaseFilename());
238 
239     static bool initialized = false;
240     if (!initialized) {
241         atexit(closeIconDatabaseOnExit);
242         initialized = true;
243     }
244 }
245 
246 /**
247  * webkit_icon_database_get_icon_uri:
248  * @database: a #WebKitIconDatabase
249  * @page_uri: URI of the page containing the icon
250  *
251  * Obtains the URI for the favicon for the given page URI.
252  * See also webkit_web_view_get_icon_uri().
253  *
254  * Returns: a newly allocated URI for the favicon, or %NULL
255  *
256  * Since: 1.3.13
257  **/
webkit_icon_database_get_icon_uri(WebKitIconDatabase * database,const gchar * pageURI)258 gchar* webkit_icon_database_get_icon_uri(WebKitIconDatabase* database, const gchar* pageURI)
259 {
260     g_return_val_if_fail(WEBKIT_IS_ICON_DATABASE(database), 0);
261     g_return_val_if_fail(pageURI, 0);
262 
263     String pageURL = String::fromUTF8(pageURI);
264     return g_strdup(WebCore::iconDatabase().synchronousIconURLForPageURL(pageURL).utf8().data());
265 }
266 
267 /**
268  * webkit_icon_database_get_icon_pixbuf:
269  * @database: a #WebKitIconDatabase
270  * @page_uri: URI of the page containing the icon
271  *
272  * Obtains a #GdkPixbuf of the favicon for the given page URI, or
273  * a default icon if there is no icon for the given page. Use
274  * webkit_icon_database_get_icon_uri() if you need to distinguish these cases.
275  * Usually you want to connect to WebKitIconDatabase::icon-loaded and call this
276  * method in the callback.
277  *
278  * The pixbuf will have the largest size provided by the server and should
279  * be resized before it is displayed.
280  * See also webkit_web_view_get_icon_pixbuf().
281  *
282  * Returns: (transfer full): a new reference to a #GdkPixbuf, or %NULL
283  *
284  * Since: 1.3.13
285  **/
webkit_icon_database_get_icon_pixbuf(WebKitIconDatabase * database,const gchar * pageURI)286 GdkPixbuf* webkit_icon_database_get_icon_pixbuf(WebKitIconDatabase* database, const gchar* pageURI)
287 {
288     g_return_val_if_fail(WEBKIT_IS_ICON_DATABASE(database), 0);
289     g_return_val_if_fail(pageURI, 0);
290 
291     String pageURL = String::fromUTF8(pageURI);
292     // The exact size we pass is irrelevant to the WebCore::iconDatabase code.
293     // We must pass something greater than 0, 0 to get a pixbuf.
294     WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(pageURL, WebCore::IntSize(16, 16));
295     if (!icon)
296         return 0;
297     GdkPixbuf* pixbuf = icon->getGdkPixbuf();
298     if (!pixbuf)
299         return 0;
300     return static_cast<GdkPixbuf*>(g_object_ref(pixbuf));
301 }
302 
303 /**
304  * webkit_icon_database_clear():
305  * @database: a #WebKitIconDatabase
306  *
307  * Clears all icons from the database.
308  *
309  * Since: 1.3.13
310  **/
webkit_icon_database_clear(WebKitIconDatabase * database)311 void webkit_icon_database_clear(WebKitIconDatabase* database)
312 {
313     g_return_if_fail(WEBKIT_IS_ICON_DATABASE(database));
314 
315     WebCore::iconDatabase().removeAllIcons();
316 }
317 
318