Home | History | Annotate | Download | only in webkit
      1 /*
      2  * Copyright (C) 2007 Holger Hans Peter Freyther
      3  * Copyright (C) 2008 Collabora Ltd.
      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 "webkitsoupauthdialog.h"
     24 #include "webkitprivate.h"
     25 #include "ApplicationCacheStorage.h"
     26 #include "Chrome.h"
     27 #include "ChromeClientGtk.h"
     28 #include "Frame.h"
     29 #include "FrameLoader.h"
     30 #include "FrameLoaderClientGtk.h"
     31 #include "HitTestResult.h"
     32 #include "IconDatabase.h"
     33 #include <libintl.h>
     34 #include "Logging.h"
     35 #include "PageCache.h"
     36 #include "PageGroup.h"
     37 #include "Pasteboard.h"
     38 #include "PasteboardHelperGtk.h"
     39 #include "ResourceHandle.h"
     40 #include "ResourceHandleClient.h"
     41 #include "ResourceHandleInternal.h"
     42 #include "ResourceResponse.h"
     43 #include <runtime/InitializeThreading.h>
     44 #include "SecurityOrigin.h"
     45 #include <stdlib.h>
     46 #include "TextEncodingRegistry.h"
     47 #include "webkitnetworkresponse.h"
     48 
     49 #if ENABLE(DATABASE)
     50 #include "DatabaseTracker.h"
     51 #endif
     52 
     53 using namespace WebCore;
     54 
     55 namespace WebKit {
     56 
     57 WebKitWebView* getViewFromFrame(WebKitWebFrame* frame)
     58 {
     59     WebKitWebFramePrivate* priv = frame->priv;
     60     return priv->webView;
     61 }
     62 
     63 WebCore::Frame* core(WebKitWebFrame* frame)
     64 {
     65     if (!frame)
     66         return 0;
     67 
     68     WebKitWebFramePrivate* priv = frame->priv;
     69     return priv ? priv->coreFrame : 0;
     70 }
     71 
     72 WebKitWebFrame* kit(WebCore::Frame* coreFrame)
     73 {
     74     if (!coreFrame)
     75         return 0;
     76 
     77     ASSERT(coreFrame->loader());
     78     WebKit::FrameLoaderClient* client = static_cast<WebKit::FrameLoaderClient*>(coreFrame->loader()->client());
     79     return client ? client->webFrame() : 0;
     80 }
     81 
     82 WebCore::Page* core(WebKitWebView* webView)
     83 {
     84     if (!webView)
     85         return 0;
     86 
     87     WebKitWebViewPrivate* priv = webView->priv;
     88     return priv ? priv->corePage : 0;
     89 }
     90 
     91 WebKitWebView* kit(WebCore::Page* corePage)
     92 {
     93     if (!corePage)
     94         return 0;
     95 
     96     ASSERT(corePage->chrome());
     97     WebKit::ChromeClient* client = static_cast<WebKit::ChromeClient*>(corePage->chrome()->client());
     98     return client ? client->webView() : 0;
     99 }
    100 
    101 WebKitWebNavigationReason kit(WebCore::NavigationType type)
    102 {
    103     return (WebKitWebNavigationReason)type;
    104 }
    105 
    106 WebCore::NavigationType core(WebKitWebNavigationReason type)
    107 {
    108     return static_cast<WebCore::NavigationType>(type);
    109 }
    110 
    111 WebCore::ResourceRequest core(WebKitNetworkRequest* request)
    112 {
    113     SoupMessage* soupMessage = webkit_network_request_get_message(request);
    114     if (soupMessage)
    115         return ResourceRequest(soupMessage);
    116 
    117     KURL url = KURL(KURL(), String::fromUTF8(webkit_network_request_get_uri(request)));
    118     return ResourceRequest(url);
    119 }
    120 
    121 WebCore::ResourceResponse core(WebKitNetworkResponse* response)
    122 {
    123     SoupMessage* soupMessage = webkit_network_response_get_message(response);
    124     if (soupMessage)
    125         return ResourceResponse(soupMessage);
    126 
    127     return ResourceResponse();
    128 }
    129 
    130 WebCore::EditingBehavior core(WebKitEditingBehavior type)
    131 {
    132     return (WebCore::EditingBehavior)type;
    133 }
    134 
    135 WebKitHitTestResult* kit(const WebCore::HitTestResult& result)
    136 {
    137     guint context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
    138     GOwnPtr<char> linkURI(0);
    139     GOwnPtr<char> imageURI(0);
    140     GOwnPtr<char> mediaURI(0);
    141 
    142     if (!result.absoluteLinkURL().isEmpty()) {
    143         context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK;
    144         linkURI.set(g_strdup(result.absoluteLinkURL().string().utf8().data()));
    145     }
    146 
    147     if (!result.absoluteImageURL().isEmpty()) {
    148         context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
    149         imageURI.set(g_strdup(result.absoluteImageURL().string().utf8().data()));
    150     }
    151 
    152     if (!result.absoluteMediaURL().isEmpty()) {
    153         context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;
    154         mediaURI.set(g_strdup(result.absoluteMediaURL().string().utf8().data()));
    155     }
    156 
    157     if (result.isSelected())
    158         context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
    159 
    160     if (result.isContentEditable())
    161         context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
    162 
    163     return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT,
    164                                            "link-uri", linkURI.get(),
    165                                            "image-uri", imageURI.get(),
    166                                            "media-uri", mediaURI.get(),
    167                                            "context", context,
    168                                            NULL));
    169 }
    170 
    171 PasteboardHelperGtk* pasteboardHelperInstance()
    172 {
    173     static PasteboardHelperGtk* helper = new PasteboardHelperGtk();
    174     return helper;
    175 }
    176 
    177 } /** end namespace WebKit */
    178 
    179 namespace WTF {
    180 
    181 template <> void freeOwnedGPtr<SoupMessage>(SoupMessage* soupMessage)
    182 {
    183     if (soupMessage)
    184         g_object_unref(soupMessage);
    185 }
    186 
    187 template <> void freeOwnedGPtr<WebKitNetworkRequest>(WebKitNetworkRequest* request)
    188 {
    189     if (request)
    190         g_object_unref(request);
    191 }
    192 
    193 template <> void freeOwnedGPtr<WebKitNetworkResponse>(WebKitNetworkResponse* response)
    194 {
    195     if (response)
    196         g_object_unref(response);
    197 }
    198 
    199 template <> void freeOwnedGPtr<WebKitWebResource>(WebKitWebResource* resource)
    200 {
    201     if (resource)
    202         g_object_unref(resource);
    203 }
    204 
    205 }
    206 
    207 static GtkWidget* currentToplevelCallback(WebKitSoupAuthDialog* feature, SoupMessage* message, gpointer userData)
    208 {
    209     gpointer messageData = g_object_get_data(G_OBJECT(message), "resourceHandle");
    210     if (!messageData)
    211         return NULL;
    212 
    213     ResourceHandle* handle = static_cast<ResourceHandle*>(messageData);
    214     if (!handle)
    215         return NULL;
    216 
    217     ResourceHandleInternal* d = handle->getInternal();
    218     if (!d)
    219         return NULL;
    220 
    221     WebCore::Frame* frame = d->m_frame;
    222     if (!frame)
    223         return NULL;
    224 
    225     GtkWidget* toplevel =  gtk_widget_get_toplevel(GTK_WIDGET(frame->page()->chrome()->platformPageClient()));
    226 #if GTK_CHECK_VERSION(2, 18, 0)
    227     if (gtk_widget_is_toplevel(toplevel))
    228 #else
    229     if (GTK_WIDGET_TOPLEVEL(toplevel))
    230 #endif
    231         return toplevel;
    232     else
    233         return NULL;
    234 }
    235 
    236 static void closeIconDatabaseOnExit()
    237 {
    238     iconDatabase()->close();
    239 }
    240 
    241 void webkit_init()
    242 {
    243     static bool isInitialized = false;
    244     if (isInitialized)
    245         return;
    246     isInitialized = true;
    247 
    248     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
    249     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
    250 
    251     JSC::initializeThreading();
    252     WebCore::InitializeLoggingChannelsIfNecessary();
    253 
    254     // We make sure the text codecs have been initialized, because
    255     // that may only be done by the main thread.
    256     atomicCanonicalTextEncodingName("UTF-8");
    257 
    258     // Page cache capacity (in pages). Comment from Mac port:
    259     // (Research indicates that value / page drops substantially after 3 pages.)
    260     // FIXME: Expose this with an API and/or calculate based on available resources
    261     webkit_set_cache_model(WEBKIT_CACHE_MODEL_WEB_BROWSER);
    262 
    263 #if ENABLE(DATABASE)
    264     gchar* databaseDirectory = g_build_filename(g_get_user_data_dir(), "webkit", "databases", NULL);
    265     webkit_set_web_database_directory_path(databaseDirectory);
    266 
    267     // FIXME: It should be possible for client applications to override the default appcache location
    268     WebCore::cacheStorage().setCacheDirectory(databaseDirectory);
    269     g_free(databaseDirectory);
    270 #endif
    271 
    272     PageGroup::setShouldTrackVisitedLinks(true);
    273 
    274     Pasteboard::generalPasteboard()->setHelper(WebKit::pasteboardHelperInstance());
    275 
    276     iconDatabase()->setEnabled(true);
    277 
    278     GOwnPtr<gchar> iconDatabasePath(g_build_filename(g_get_user_data_dir(), "webkit", "icondatabase", NULL));
    279     iconDatabase()->open(iconDatabasePath.get());
    280 
    281     atexit(closeIconDatabaseOnExit);
    282 
    283     SoupSession* session = webkit_get_default_session();
    284 
    285     SoupSessionFeature* authDialog = static_cast<SoupSessionFeature*>(g_object_new(WEBKIT_TYPE_SOUP_AUTH_DIALOG, NULL));
    286     g_signal_connect(authDialog, "current-toplevel", G_CALLBACK(currentToplevelCallback), NULL);
    287     soup_session_add_feature(session, authDialog);
    288     g_object_unref(authDialog);
    289 
    290     SoupSessionFeature* sniffer = static_cast<SoupSessionFeature*>(g_object_new(SOUP_TYPE_CONTENT_SNIFFER, NULL));
    291     soup_session_add_feature(session, sniffer);
    292     g_object_unref(sniffer);
    293 
    294     soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
    295 }
    296 
    297 void webkit_white_list_access_from_origin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains)
    298 {
    299     SecurityOrigin::whiteListAccessFromOrigin(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
    300 }
    301 
    302 void webkit_reset_origin_access_white_lists()
    303 {
    304     SecurityOrigin::resetOriginAccessWhiteLists();
    305 }
    306