Home | History | Annotate | Download | only in webkit
      1 /*
      2  * Copyright (C) 2011 Christian Dywan <christian (at) 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 
     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 
     94 static void webkit_icon_database_dispose(GObject* object)
     95 {
     96     G_OBJECT_CLASS(webkit_icon_database_parent_class)->dispose(object);
     97 }
     98 
     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 
    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 
    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 
    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  **/
    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 
    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  **/
    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  **/
    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  **/
    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  **/
    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