diff options
Diffstat (limited to 'WebKit/gtk/webkit')
-rw-r--r-- | WebKit/gtk/webkit/webkit.h | 2 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitdefines.h | 3 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitdownload.cpp | 818 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitdownload.h | 114 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitprivate.cpp | 36 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitprivate.h | 32 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitsoupauthdialog.c | 347 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitsoupauthdialog.h | 49 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebbackforwardlist.cpp | 32 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebbackforwardlist.h | 3 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebframe.cpp | 67 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebframe.h | 11 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebhistoryitem.cpp | 141 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebinspector.cpp | 41 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebsettings.cpp | 27 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebview.cpp | 442 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebview.h | 36 |
17 files changed, 2098 insertions, 103 deletions
diff --git a/WebKit/gtk/webkit/webkit.h b/WebKit/gtk/webkit/webkit.h index 8c868a2..c22165e 100644 --- a/WebKit/gtk/webkit/webkit.h +++ b/WebKit/gtk/webkit/webkit.h @@ -23,7 +23,9 @@ #include <webkit/webkitversion.h> #include <webkit/webkitdefines.h> +#include <webkit/webkitdownload.h> #include <webkit/webkitnetworkrequest.h> +#include <webkit/webkitsoupauthdialog.h> #include <webkit/webkitwebframe.h> #include <webkit/webkitwebsettings.h> #include <webkit/webkitwebinspector.h> diff --git a/WebKit/gtk/webkit/webkitdefines.h b/WebKit/gtk/webkit/webkitdefines.h index f94e710..b0ab5e9 100644 --- a/WebKit/gtk/webkit/webkitdefines.h +++ b/WebKit/gtk/webkit/webkitdefines.h @@ -68,6 +68,9 @@ typedef struct _WebKitWebWindowFeaturesClass WebKitWebWindowFeaturesClass; typedef struct _WebKitWebView WebKitWebView; typedef struct _WebKitWebViewClass WebKitWebViewClass; +typedef struct _WebKitDownload WebKitDownload; +typedef struct _WebKitDownloadClass WebKitDownloadClass; + G_END_DECLS #endif diff --git a/WebKit/gtk/webkit/webkitdownload.cpp b/WebKit/gtk/webkit/webkitdownload.cpp new file mode 100644 index 0000000..4488304 --- /dev/null +++ b/WebKit/gtk/webkit/webkitdownload.cpp @@ -0,0 +1,818 @@ +/* + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "CString.h" +#include "Noncopyable.h" +#include "NotImplemented.h" +#include "ResourceHandleClient.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include "webkitdownload.h" +#include "webkitenumtypes.h" +#include "webkitmarshal.h" +#include "webkitprivate.h" + +#include <glib/gstdio.h> + +using namespace WebKit; +using namespace WebCore; + +class DownloadClient : Noncopyable, public ResourceHandleClient { + public: + DownloadClient(WebKitDownload*); + + virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); + virtual void didReceiveData(ResourceHandle*, const char*, int, int); + virtual void didFinishLoading(ResourceHandle*); + virtual void didFail(ResourceHandle*, const ResourceError&); + virtual void wasBlocked(ResourceHandle*); + virtual void cannotShowURL(ResourceHandle*); + + private: + WebKitDownload* m_download; +}; + +extern "C" { + +#define WEBKIT_DOWNLOAD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_DOWNLOAD, WebKitDownloadPrivate)) + +struct _WebKitDownloadPrivate { + gchar* destinationURI; + gchar* suggestedFilename; + guint currentSize; + GTimer* timer; + WebKitDownloadStatus status; + GFileOutputStream* outputStream; + DownloadClient* downloadClient; + WebKitNetworkRequest* networkRequest; + ResourceResponse* networkResponse; + RefPtr<ResourceHandle> resourceHandle; +}; + +enum { + // Normal signals. + ERROR, + LAST_SIGNAL +}; + +static guint webkit_download_signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + + PROP_NETWORK_REQUEST, + PROP_DESTINATION_URI, + PROP_SUGGESTED_FILENAME, + PROP_PROGRESS, + PROP_STATUS, + PROP_CURRENT_SIZE, + PROP_TOTAL_SIZE +}; + +G_DEFINE_TYPE(WebKitDownload, webkit_download, G_TYPE_OBJECT); + + +static void webkit_download_set_status(WebKitDownload* download, WebKitDownloadStatus status); + +static void webkit_download_dispose(GObject* object) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + WebKitDownloadPrivate* priv = download->priv; + + if (priv->outputStream) { + g_object_unref(priv->outputStream); + priv->outputStream = NULL; + } + + if (priv->networkRequest) { + g_object_unref(priv->networkRequest); + priv->networkRequest = NULL; + } + + G_OBJECT_CLASS(webkit_download_parent_class)->dispose(object); +} + +static void webkit_download_finalize(GObject* object) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + WebKitDownloadPrivate* priv = download->priv; + + // We don't call webkit_download_cancel() because we don't want to emit + // signals when finalizing an object. + if (priv->resourceHandle) { + if (priv->status == WEBKIT_DOWNLOAD_STATUS_STARTED) { + priv->resourceHandle->setClient(0); + priv->resourceHandle->cancel(); + } + priv->resourceHandle.release(); + } + + delete priv->downloadClient; + delete priv->networkResponse; + + // The download object may never have _start called on it, so we + // need to make sure timer is non-NULL. + if (priv->timer) + g_timer_destroy(priv->timer); + + g_free(priv->destinationURI); + g_free(priv->suggestedFilename); + + G_OBJECT_CLASS(webkit_download_parent_class)->finalize(object); +} + +static void webkit_download_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + + switch(prop_id) { + case PROP_NETWORK_REQUEST: + g_value_set_object(value, webkit_download_get_network_request(download)); + break; + case PROP_DESTINATION_URI: + g_value_set_string(value, webkit_download_get_destination_uri(download)); + break; + case PROP_SUGGESTED_FILENAME: + g_value_set_string(value, webkit_download_get_suggested_filename(download)); + break; + case PROP_PROGRESS: + g_value_set_double(value, webkit_download_get_progress(download)); + break; + case PROP_STATUS: + g_value_set_enum(value, webkit_download_get_status(download)); + break; + case PROP_CURRENT_SIZE: + g_value_set_uint64(value, webkit_download_get_current_size(download)); + break; + case PROP_TOTAL_SIZE: + g_value_set_uint64(value, webkit_download_get_total_size(download)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void webkit_download_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec *pspec) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + WebKitDownloadPrivate* priv = download->priv; + + switch(prop_id) { + case PROP_NETWORK_REQUEST: + priv->networkRequest = WEBKIT_NETWORK_REQUEST(g_value_dup_object(value)); + // This is safe as network-request is a construct only property and + // suggestedFilename is initially null. + priv->suggestedFilename = g_path_get_basename(webkit_network_request_get_uri(priv->networkRequest)); + break; + case PROP_DESTINATION_URI: + webkit_download_set_destination_uri(download, g_value_get_string(value)); + break; + case PROP_STATUS: + webkit_download_set_status(download, static_cast<WebKitDownloadStatus>(g_value_get_enum(value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void webkit_download_class_init(WebKitDownloadClass* downloadClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(downloadClass); + objectClass->dispose = webkit_download_dispose; + objectClass->finalize = webkit_download_finalize; + objectClass->get_property = webkit_download_get_property; + objectClass->set_property = webkit_download_set_property; + + /** + * WebKitDownload::error: + * @download: the object on which the signal is emitted + * @current_bytes: the current count of bytes downloaded + * @total_bytes: the total bytes count in the downloaded file, aka file size. + * + * Indicates an error in the download. + * + * Since: 1.1.2 + */ + webkit_download_signals[ERROR] = g_signal_new("error", + G_TYPE_FROM_CLASS(downloadClass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + g_signal_accumulator_true_handled, + NULL, + webkit_marshal_BOOLEAN__INT_INT_STRING, + G_TYPE_BOOLEAN, 3, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_STRING); + + // Properties. + + /** + * WebKitDownload:network-request + * + * The #WebKitNetworkRequest instance associated with the download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_NETWORK_REQUEST, + g_param_spec_object("network-request", + "Network Request", + "The network request for the URI that should be downloaded", + WEBKIT_TYPE_NETWORK_REQUEST, + (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitDownload:destination-uri + * + * The URI of the save location for this download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_DESTINATION_URI, + g_param_spec_string("destination-uri", + "Destination URI", + "The destination URI where to save the file", + "", + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitDownload:suggested-filename + * + * The file name suggested as default when saving + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_SUGGESTED_FILENAME, + g_param_spec_string("suggested-filename", + "Suggested Filename", + "The filename suggested as default when saving", + "", + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:progress: + * + * Determines the current progress of the download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_PROGRESS, + g_param_spec_double("progress", + "Progress", + "Determines the current progress of the download", + 0.0, 1.0, 1.0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:status: + * + * Determines the current status of the download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_STATUS, + g_param_spec_enum("status", + "Status", + "Determines the current status of the download", + WEBKIT_TYPE_DOWNLOAD_STATUS, + WEBKIT_DOWNLOAD_STATUS_CREATED, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:current-size + * + * The length of the data already downloaded + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_CURRENT_SIZE, + g_param_spec_uint64("current-size", + "Current Size", + "The length of the data already downloaded", + 0, G_MAXUINT64, 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:total-size + * + * The total size of the file + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_CURRENT_SIZE, + g_param_spec_uint64("total-size", + "Total Size", + "The total size of the file", + 0, G_MAXUINT64, 0, + WEBKIT_PARAM_READABLE)); + + g_type_class_add_private(downloadClass, sizeof(WebKitDownloadPrivate)); +} + +static void webkit_download_init(WebKitDownload* download) +{ + WebKitDownloadPrivate* priv = WEBKIT_DOWNLOAD_GET_PRIVATE(download); + download->priv = priv; + + priv->downloadClient = new DownloadClient(download); + priv->currentSize = 0; + priv->status = WEBKIT_DOWNLOAD_STATUS_CREATED; +} + +/** + * webkit_download_new: + * @request: a #WebKitNetworkRequest + * + * Creates a new #WebKitDownload object for the given + * #WebKitNetworkRequest object. + * + * Returns: the new #WebKitDownload + * + * Since: 1.1.2 + */ +WebKitDownload* webkit_download_new(WebKitNetworkRequest* request) +{ + g_return_val_if_fail(request, NULL); + + return WEBKIT_DOWNLOAD(g_object_new(WEBKIT_TYPE_DOWNLOAD, "network-request", request, NULL)); +} + +static gboolean webkit_download_open_stream_for_uri(WebKitDownload* download, const gchar* uri, gboolean append=FALSE) +{ + g_return_val_if_fail(uri, FALSE); + + WebKitDownloadPrivate* priv = download->priv; + GFile* file = g_file_new_for_uri(uri); + GError* error = NULL; + + if (append) + priv->outputStream = g_file_append_to(file, G_FILE_CREATE_NONE, NULL, &error); + else + priv->outputStream = g_file_replace(file, NULL, TRUE, G_FILE_CREATE_NONE, NULL, &error); + + g_object_unref(file); + + if (error) { + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_DESTINATION, error->message, &handled); + g_error_free(error); + return FALSE; + } + + return TRUE; +} + +static void webkit_download_close_stream(WebKitDownload* download) +{ + WebKitDownloadPrivate* priv = download->priv; + if (priv->outputStream) { + g_object_unref(priv->outputStream); + priv->outputStream = NULL; + } +} + +/** + * webkit_download_start: + * @download: the #WebKitDownload + * + * Initiates the download. Notice that you must have set the + * destination-uri property before calling this method. + * + * Since: 1.1.2 + */ +void webkit_download_start(WebKitDownload* download) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + WebKitDownloadPrivate* priv = download->priv; + g_return_if_fail(priv->destinationURI); + g_return_if_fail(priv->status == WEBKIT_DOWNLOAD_STATUS_CREATED); + g_return_if_fail(priv->timer == NULL); + + if (priv->resourceHandle) + priv->resourceHandle->setClient(priv->downloadClient); + else { + // FIXME: Use the actual request object when WebKitNetworkRequest is finished. + ResourceRequest request(webkit_network_request_get_uri(priv->networkRequest)); + priv->resourceHandle = ResourceHandle::create(request, priv->downloadClient, 0, false, false, false); + } + + priv->timer = g_timer_new(); + webkit_download_open_stream_for_uri(download, priv->destinationURI); +} + +/** + * webkit_download_cancel: + * @download: the #WebKitDownload + * + * Cancels the download. Calling this will not free the + * #WebKitDownload object, so you still need to call + * g_object_unref() on it, if you are the owner of a reference. Notice + * that cancelling the download provokes the emission of the + * WebKitDownload::error signal, reporting that the download was + * cancelled. + * + * Since: 1.1.2 + */ +void webkit_download_cancel(WebKitDownload* download) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + WebKitDownloadPrivate* priv = download->priv; + + // Cancel may be called even if start was not called, so we need + // to make sure timer is non-NULL. + if (priv->timer) + g_timer_stop(priv->timer); + + if (priv->resourceHandle) + priv->resourceHandle->cancel(); + + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_CANCELLED); + + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, "User cancelled the download", &handled); +} + +/** + * webkit_download_get_uri: + * @download: the #WebKitDownload + * + * Convenience method to retrieve the URI from the + * #WebKitNetworkRequest which is being downloaded. + * + * Returns: the uri + * + * Since: 1.1.2 + */ +const gchar* webkit_download_get_uri(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return webkit_network_request_get_uri(priv->networkRequest); +} + +/** + * webkit_download_get_network_request: + * @download: the #WebKitDownload + * + * Retrieves the #WebKitNetworkRequest object that backs the download + * process. + * + * Returns: the #WebKitNetworkRequest instance + * + * Since: 1.1.2 + */ +WebKitNetworkRequest* webkit_download_get_network_request(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return priv->networkRequest; +} + +static void webkit_download_set_response(WebKitDownload* download, const ResourceResponse& response) +{ + // FIXME Use WebKitNetworkResponse when it's merged. + WebKitDownloadPrivate* priv = download->priv; + priv->networkResponse = new ResourceResponse(response); +} + +/** + * webkit_download_get_suggested_filename: + * @download: the #WebKitDownload + * + * Retrieves the filename that was suggested by the server, or the one + * derived by WebKit from the URI. + * + * Returns: the suggested filename + * + * Since: 1.1.2 + */ +const gchar* webkit_download_get_suggested_filename(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return priv->suggestedFilename; +} + +/** + * webkit_download_get_destination_uri: + * @download: the #WebKitDownload + * + * Obtains the URI to which the downloaded file will be written. This + * must have been set by the application before calling + * webkit_download_start(), and may be %NULL. + * + * Returns: the destination URI or %NULL + * + * Since: 1.1.2 + */ +const gchar* webkit_download_get_destination_uri(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return priv->destinationURI; +} + +/** + * webkit_download_set_destination_uri: + * @download: the #WebKitDownload + * @destination_uri: the destination URI + * + * Defines the URI that should be used to save the downloaded file to. + * + * Since: 1.1.2 + */ +void webkit_download_set_destination_uri(WebKitDownload* download, const gchar* destination_uri) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + g_return_if_fail(destination_uri); + + WebKitDownloadPrivate* priv = download->priv; + if (priv->destinationURI && !strcmp(priv->destinationURI, destination_uri)) + return; + + if (priv->status != WEBKIT_DOWNLOAD_STATUS_CREATED && priv->status != WEBKIT_DOWNLOAD_STATUS_CANCELLED) { + ASSERT(priv->destinationURI); + + gboolean downloading = priv->outputStream != NULL; + if (downloading) + webkit_download_close_stream(download); + + GFile* src = g_file_new_for_uri(priv->destinationURI); + GFile* dest = g_file_new_for_uri(destination_uri); + GError* error = NULL; + + g_file_move(src, dest, G_FILE_COPY_BACKUP, NULL, NULL, NULL, &error); + + g_object_unref(src); + g_object_unref(dest); + + g_free(priv->destinationURI); + priv->destinationURI = g_strdup(destination_uri); + + if (error) { + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_DESTINATION, error->message, &handled); + g_error_free(error); + return; + } + + if (downloading) { + if (!webkit_download_open_stream_for_uri(download, destination_uri, TRUE)) { + webkit_download_cancel(download); + return; + } + } + } else { + g_free(priv->destinationURI); + priv->destinationURI = g_strdup(destination_uri); + } + + // Only notify change if everything went fine. + g_object_notify(G_OBJECT(download), "destination-uri"); +} + +/** + * webkit_download_get_status: + * @download: the #WebKitDownload + * + * Obtains the current status of the download, as a + * #WebKitDownloadStatus. + * + * Returns: the current #WebKitDownloadStatus + * + * Since: 1.1.2 + */ +WebKitDownloadStatus webkit_download_get_status(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), WEBKIT_DOWNLOAD_STATUS_ERROR); + + WebKitDownloadPrivate* priv = download->priv; + return priv->status; +} + +static void webkit_download_set_status(WebKitDownload* download, WebKitDownloadStatus status) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + WebKitDownloadPrivate* priv = download->priv; + priv->status = status; + + g_object_notify(G_OBJECT(download), "status"); +} + +/** + * webkit_download_get_total_size: + * @download: the #WebKitDownload + * + * Returns the expected total size of the download. This is expected + * because the server may provide incorrect or missing + * Content-Length. Notice that this may grow over time, as it will be + * always the same as current_size in the cases where current size + * surpasses it. + * + * Returns: the expected total size of the downloaded file + * + * Since: 1.1.2 + */ +guint64 webkit_download_get_total_size(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0); + + WebKitDownloadPrivate* priv = download->priv; + if (!priv->networkResponse) + return 0; + + return MAX(priv->currentSize, priv->networkResponse->expectedContentLength()); +} + +/** + * webkit_download_get_current_size: + * @download: the #WebKitDownload + * + * Current already downloaded size. + * + * Returns: the already downloaded size + * + * Since: 1.1.2 + */ +guint64 webkit_download_get_current_size(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0); + + WebKitDownloadPrivate* priv = download->priv; + return priv->currentSize; +} + +/** + * webkit_download_get_progress: + * @download: a #WebKitDownload + * + * Determines the current progress of the download. + * + * Returns: a #gdouble ranging from 0.0 to 1.0. + * + * Since: 1.1.2 + */ +gdouble webkit_download_get_progress(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 1.0); + + WebKitDownloadPrivate* priv = download->priv; + gdouble total_size = (gdouble)priv->networkResponse->expectedContentLength(); + + if (total_size == 0) + return 1.0; + + return ((gdouble)priv->currentSize) / total_size; +} + +/** + * webkit_download_get_elapsed_time: + * @download: a #WebKitDownload + * + * Elapsed time for the download in seconds, including any fractional + * part. If the download is finished, had an error or was cancelled + * this is the time between its start and the event. + * + * Returns: seconds since the download was started, as a #gdouble + * + * Since: 1.1.2 + */ +gdouble webkit_download_get_elapsed_time(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0.0); + + WebKitDownloadPrivate* priv = download->priv; + return g_timer_elapsed(priv->timer, NULL); +} + +static void webkit_download_received_data(WebKitDownload* download, const gchar* data, int length) +{ + WebKitDownloadPrivate* priv = download->priv; + + if (priv->currentSize == 0) + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_STARTED); + + ASSERT(priv->outputStream); + + gsize bytes_written; + GError* error = NULL; + + g_output_stream_write_all(G_OUTPUT_STREAM(priv->outputStream), + data, length, &bytes_written, NULL, &error); + + if (error) { + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_DESTINATION, error->message, &handled); + g_error_free(error); + return; + } + + priv->currentSize += length; + g_object_notify(G_OBJECT(download), "current-size"); + + ASSERT(priv->networkResponse); + if (priv->currentSize > priv->networkResponse->expectedContentLength()) + g_object_notify(G_OBJECT(download), "total-size"); + + // FIXME: Throttle the number of updates? Should we remove the + // previous g_object_notify()s if we are going to throttle the + // progress updates? + g_object_notify(G_OBJECT(download), "progress"); +} + +static void webkit_download_finished_loading(WebKitDownload* download) +{ + webkit_download_close_stream(download); + + WebKitDownloadPrivate* priv = download->priv; + + g_timer_stop(priv->timer); + + g_object_notify(G_OBJECT(download), "progress"); + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_FINISHED); +} + +static void webkit_download_error(WebKitDownload* download, const ResourceError& error) +{ + webkit_download_close_stream(download); + + WebKitDownloadPrivate* priv = download->priv; + + g_timer_stop(priv->timer); + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_ERROR); + + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_NETWORK, error.localizedDescription().utf8().data(), &handled); +} + +DownloadClient::DownloadClient(WebKitDownload* download) + : m_download(download) +{ +} + +void DownloadClient::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) +{ + webkit_download_set_response(m_download, response); +} + +void DownloadClient::didReceiveData(ResourceHandle*, const char* data, int length, int lengthReceived) +{ + webkit_download_received_data(m_download, data, length); +} + +void DownloadClient::didFinishLoading(ResourceHandle*) +{ + webkit_download_finished_loading(m_download); +} + +void DownloadClient::didFail(ResourceHandle*, const ResourceError& error) +{ + webkit_download_error(m_download, error); +} + +void DownloadClient::wasBlocked(ResourceHandle*) +{ + // FIXME: Implement this when we have the new frame loader signals + // and error handling. + notImplemented(); +} + +void DownloadClient::cannotShowURL(ResourceHandle*) +{ + // FIXME: Implement this when we have the new frame loader signals + // and error handling. + notImplemented(); +} + +} diff --git a/WebKit/gtk/webkit/webkitdownload.h b/WebKit/gtk/webkit/webkitdownload.h new file mode 100644 index 0000000..7c86c65 --- /dev/null +++ b/WebKit/gtk/webkit/webkitdownload.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WEBKIT_DOWNLOAD_H +#define WEBKIT_DOWNLOAD_H + +#include <webkit/webkitdefines.h> + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_DOWNLOAD (webkit_download_get_type()) +#define WEBKIT_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_DOWNLOAD, WebKitDownload)) +#define WEBKIT_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_DOWNLOAD, WebKitDownloadClass)) +#define WEBKIT_IS_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_DOWNLOAD)) +#define WEBKIT_IS_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_DOWNLOAD)) +#define WEBKIT_DOWNLOAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_DOWNLOAD, WebKitDownloadClass)) + +typedef enum { + WEBKIT_DOWNLOAD_STATUS_ERROR = -1, + WEBKIT_DOWNLOAD_STATUS_CREATED = 0, + WEBKIT_DOWNLOAD_STATUS_STARTED, + WEBKIT_DOWNLOAD_STATUS_CANCELLED, + WEBKIT_DOWNLOAD_STATUS_FINISHED +} WebKitDownloadStatus; + +typedef enum { + WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, + WEBKIT_DOWNLOAD_ERROR_DESTINATION, + WEBKIT_DOWNLOAD_ERROR_NETWORK +} WebKitDownloadError; + +typedef struct _WebKitDownloadPrivate WebKitDownloadPrivate; + +struct _WebKitDownload { + GObject parent_instance; + + WebKitDownloadPrivate *priv; +}; + +struct _WebKitDownloadClass { + GObjectClass parent_class; + + /* Padding for future expansion */ + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_download_get_type (void); + +WEBKIT_API WebKitDownload* +webkit_download_new (WebKitNetworkRequest *request); + +WEBKIT_API void +webkit_download_start (WebKitDownload *download); + +WEBKIT_API void +webkit_download_cancel (WebKitDownload *download); + +WEBKIT_API const gchar* +webkit_download_get_uri (WebKitDownload *download); + +WEBKIT_API WebKitNetworkRequest* +webkit_download_get_network_request (WebKitDownload *download); + +WEBKIT_API const gchar* +webkit_download_get_suggested_filename (WebKitDownload *download); + +WEBKIT_API const gchar* +webkit_download_get_destination_uri (WebKitDownload *download); + +WEBKIT_API void +webkit_download_set_destination_uri (WebKitDownload *download, + const gchar *destination_uri); + +WEBKIT_API gdouble +webkit_download_get_progress (WebKitDownload *download); + +WEBKIT_API gdouble +webkit_download_get_elapsed_time (WebKitDownload *download); + +WEBKIT_API guint64 +webkit_download_get_total_size (WebKitDownload *download); + +WEBKIT_API guint64 +webkit_download_get_current_size (WebKitDownload *download); + +WEBKIT_API WebKitDownloadStatus +webkit_download_get_status (WebKitDownload *download); + +G_END_DECLS + +#endif diff --git a/WebKit/gtk/webkit/webkitprivate.cpp b/WebKit/gtk/webkit/webkitprivate.cpp index e801981..c4264c9 100644 --- a/WebKit/gtk/webkit/webkitprivate.cpp +++ b/WebKit/gtk/webkit/webkitprivate.cpp @@ -20,8 +20,10 @@ #include "config.h" +#include "webkitsoupauthdialog.h" #include "webkitprivate.h" #include "ChromeClientGtk.h" +#include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClientGtk.h" #include "Logging.h" @@ -30,6 +32,9 @@ #include "PageGroup.h" #include "Pasteboard.h" #include "PasteboardHelperGtk.h" +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include "ResourceHandleInternal.h" #include <runtime/InitializeThreading.h> #if ENABLE(DATABASE) @@ -96,6 +101,31 @@ WebCore::NavigationType core(WebKitWebNavigationReason type) } /** end namespace WebKit */ +static GtkWidget* currentToplevelCallback(WebKitSoupAuthDialog* feature, SoupMessage* message, gpointer userData) +{ + gpointer messageData = g_object_get_data(G_OBJECT(message), "resourceHandle"); + if (!messageData) + return NULL; + + ResourceHandle* handle = static_cast<ResourceHandle*>(messageData); + if (!handle) + return NULL; + + ResourceHandleInternal* d = handle->getInternal(); + if (!d) + return NULL; + + WebCore::Frame* frame = d->m_frame; + if (!frame) + return NULL; + + GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(frame->page()->chrome()->platformWindow())); + if (GTK_WIDGET_TOPLEVEL(toplevel)) + return toplevel; + else + return NULL; +} + void webkit_init() { static bool isInitialized = false; @@ -121,4 +151,10 @@ void webkit_init() PageGroup::setShouldTrackVisitedLinks(true); Pasteboard::generalPasteboard()->setHelper(new WebKit::PasteboardHelperGtk()); + + SoupSession* session = webkit_get_default_session(); + SoupSessionFeature* authDialog = static_cast<SoupSessionFeature*>(g_object_new(WEBKIT_TYPE_SOUP_AUTH_DIALOG, NULL)); + g_signal_connect(authDialog, "current-toplevel", G_CALLBACK(currentToplevelCallback), NULL); + soup_session_add_feature(session, authDialog); + g_object_unref(authDialog); } diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h index ace996d..0b83a11 100644 --- a/WebKit/gtk/webkit/webkitprivate.h +++ b/WebKit/gtk/webkit/webkitprivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Holger Hans Peter Freyther + * Copyright (C) 2007, 2008, 2009 Holger Hans Peter Freyther * Copyright (C) 2008 Jan Michael C. Alonzo * Copyright (C) 2008 Collabora Ltd. * @@ -28,6 +28,7 @@ */ #include <webkit/webkitdefines.h> +#include <webkit/webkitdownload.h> #include <webkit/webkitwebview.h> #include <webkit/webkitwebframe.h> #include <webkit/webkitwebpolicydecision.h> @@ -43,10 +44,14 @@ #include "Frame.h" #include "InspectorClientGtk.h" #include "FrameLoaderClient.h" +#include "ResourceHandle.h" +#include "ResourceResponse.h" #include "WindowFeatures.h" #include <glib.h> +class DownloadClient; + namespace WebKit { WebKitWebView* getViewFromFrame(WebKitWebFrame*); @@ -57,7 +62,7 @@ namespace WebKit { WebKitWebView* kit(WebCore::Page*); WebCore::HistoryItem* core(WebKitWebHistoryItem*); - WebKitWebHistoryItem* kit(WebCore::HistoryItem*); + WebKitWebHistoryItem* kit(PassRefPtr<WebCore::HistoryItem>); WebCore::BackForwardList* core(WebKitWebBackForwardList*); @@ -101,6 +106,10 @@ extern "C" { GtkAdjustment* verticalAdjustment; gboolean zoomFullContent; + char* encoding; + char* customEncoding; + + gboolean disposing; }; #define WEBKIT_WEB_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate)) @@ -120,11 +129,22 @@ extern "C" { void webkit_web_frame_core_frame_gone(WebKitWebFrame*); + // WebKitWebHistoryItem private WebKitWebHistoryItem* - webkit_web_history_item_new_with_core_item(WebCore::HistoryItem*); + webkit_web_history_item_new_with_core_item(PassRefPtr<WebCore::HistoryItem> historyItem); + + WEBKIT_API G_CONST_RETURN gchar* + webkit_web_history_item_get_target(WebKitWebHistoryItem*); + + WEBKIT_API gboolean + webkit_web_history_item_is_target_item(WebKitWebHistoryItem*); + + WEBKIT_API GList* + webkit_web_history_item_get_children(WebKitWebHistoryItem*); + // end WebKitWebHistoryItem private void - webkit_web_inspector_set_inspector_client(WebKitWebInspector*, WebKit::InspectorClient*); + webkit_web_inspector_set_inspector_client(WebKitWebInspector*, WebCore::Page*); void webkit_web_inspector_set_web_view(WebKitWebInspector *web_inspector, WebKitWebView *web_view); @@ -144,6 +164,10 @@ extern "C" { void webkit_web_policy_decision_cancel (WebKitWebPolicyDecision* decision); + // FIXME: move this functionality into a 'WebKitWebDataSource' once implemented + WEBKIT_API gchar* + webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame); + // FIXME: Move these to webkitwebframe.h once their API has been discussed. WEBKIT_API GSList* diff --git a/WebKit/gtk/webkit/webkitsoupauthdialog.c b/WebKit/gtk/webkit/webkitsoupauthdialog.c new file mode 100644 index 0000000..139000b --- /dev/null +++ b/WebKit/gtk/webkit/webkitsoupauthdialog.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#if USE(GNOMEKEYRING) +#include <gnome-keyring.h> +#endif + +#include "webkitmarshal.h" +#include "webkitsoupauthdialog.h" + +static void webkit_soup_auth_dialog_session_feature_init(SoupSessionFeatureInterface* feature_interface, gpointer interface_data); +static void attach(SoupSessionFeature* manager, SoupSession* session); +static void detach(SoupSessionFeature* manager, SoupSession* session); + +enum { + CURRENT_TOPLEVEL, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE_WITH_CODE(WebKitSoupAuthDialog, webkit_soup_auth_dialog, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(SOUP_TYPE_SESSION_FEATURE, + webkit_soup_auth_dialog_session_feature_init)) + +static void webkit_soup_auth_dialog_class_init(WebKitSoupAuthDialogClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS(klass); + + signals[CURRENT_TOPLEVEL] = + g_signal_new("current-toplevel", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitSoupAuthDialogClass, current_toplevel), + NULL, NULL, + webkit_marshal_OBJECT__OBJECT, + GTK_TYPE_WIDGET, 1, + SOUP_TYPE_MESSAGE); +} + +static void webkit_soup_auth_dialog_init(WebKitSoupAuthDialog* instance) +{ +} + +static void webkit_soup_auth_dialog_session_feature_init(SoupSessionFeatureInterface *feature_interface, + gpointer interface_data) +{ + feature_interface->attach = attach; + feature_interface->detach = detach; +} + +typedef struct _WebKitAuthData { + SoupMessage* msg; + SoupAuth* auth; + SoupSession* session; + SoupSessionFeature* manager; + GtkWidget* loginEntry; + GtkWidget* passwordEntry; +#if USE(GNOMEKEYRING) + GtkWidget* checkButton; +#endif +} WebKitAuthData; + +static void free_authData(WebKitAuthData* authData) +{ + g_object_unref(authData->msg); + g_slice_free(WebKitAuthData, authData); +} + +#if USE(GNOMEKEYRING) +static void set_password_callback(GnomeKeyringResult result, guint32 val, gpointer user_data) +{ + /* Dummy callback, gnome_keyring_set_network_password does not accept a NULL one */ +} +#endif + +static void response_callback(GtkDialog* dialog, gint response_id, WebKitAuthData* authData) +{ + const char* login; + const char* password; +#if USE(GNOMEKEYRING) + SoupURI* uri; + gboolean storePassword; +#endif + + switch(response_id) { + case GTK_RESPONSE_OK: + login = gtk_entry_get_text(GTK_ENTRY(authData->loginEntry)); + password = gtk_entry_get_text(GTK_ENTRY(authData->passwordEntry)); + soup_auth_authenticate(authData->auth, login, password); + +#if USE(GNOMEKEYRING) + storePassword = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(authData->checkButton)); + if (storePassword) { + uri = soup_message_get_uri(authData->msg); + gnome_keyring_set_network_password(NULL, + login, + soup_auth_get_realm(authData->auth), + uri->host, + NULL, + uri->scheme, + soup_auth_get_scheme_name(authData->auth), + uri->port, + password, + (GnomeKeyringOperationGetIntCallback)set_password_callback, + NULL, + NULL); + } +#endif + default: + break; + } + + soup_session_unpause_message(authData->session, authData->msg); + free_authData(authData); + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +static GtkWidget * +table_add_entry (GtkWidget* table, + int row, + const char* label_text, + const char* value, + gpointer user_data) +{ + GtkWidget* entry; + GtkWidget* label; + + label = gtk_label_new(label_text); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + + entry = gtk_entry_new(); + gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); + + if (value) + gtk_entry_set_text(GTK_ENTRY(entry), value); + + gtk_table_attach(GTK_TABLE(table), label, + 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), entry, + 1, 2, row, row + 1); + + return entry; +} + +static void show_auth_dialog(WebKitAuthData* authData, const char* login, const char* password) +{ + GtkWidget* toplevel; + GtkWidget* widget; + GtkDialog* dialog; + GtkWindow* window; + GtkWidget* entryContainer; + GtkWidget* hbox; + GtkWidget* mainVBox; + GtkWidget* vbox; + GtkWidget* icon; + GtkWidget* table; + GtkWidget* messageLabel; + char* message; + SoupURI* uri; +#if USE(GNOMEKEYRING) + GtkWidget* rememberBox; + GtkWidget* checkButton; +#endif + + /* From GTK+ gtkmountoperation.c, modified and simplified. LGPL 2 license */ + + widget = gtk_dialog_new(); + window = GTK_WINDOW(widget); + dialog = GTK_DIALOG(widget); + + gtk_dialog_add_buttons(dialog, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + /* Set the dialog up with HIG properties */ + gtk_dialog_set_has_separator(dialog, FALSE); + gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing(GTK_BOX(dialog->vbox), 2); /* 2 * 5 + 2 = 12 */ + gtk_container_set_border_width(GTK_CONTAINER (dialog->action_area), 5); + gtk_box_set_spacing(GTK_BOX(dialog->action_area), 6); + + gtk_window_set_resizable(window, FALSE); + gtk_window_set_title(window, ""); + gtk_window_set_icon_name(window, GTK_STOCK_DIALOG_AUTHENTICATION); + + gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK); + + /* Get the current toplevel */ + g_signal_emit(authData->manager, signals[CURRENT_TOPLEVEL], 0, authData->msg, &toplevel); + + if (toplevel) + gtk_window_set_transient_for(window, GTK_WINDOW(toplevel)); + + /* Build contents */ + hbox = gtk_hbox_new(FALSE, 12); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); + gtk_box_pack_start(GTK_BOX(dialog->vbox), hbox, TRUE, TRUE, 0); + + icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, + GTK_ICON_SIZE_DIALOG); + + gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0.0); + gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0); + + mainVBox = gtk_vbox_new(FALSE, 18); + gtk_box_pack_start(GTK_BOX(hbox), mainVBox, TRUE, TRUE, 0); + + uri = soup_message_get_uri(authData->msg); + message = g_strdup_printf("A username and password are being requested by the site %s", uri->host); + messageLabel = gtk_label_new(message); + g_free(message); + gtk_misc_set_alignment(GTK_MISC(messageLabel), 0.0, 0.5); + gtk_label_set_line_wrap(GTK_LABEL(messageLabel), TRUE); + gtk_box_pack_start(GTK_BOX(mainVBox), GTK_WIDGET(messageLabel), + FALSE, FALSE, 0); + + vbox = gtk_vbox_new(FALSE, 6); + gtk_box_pack_start(GTK_BOX (mainVBox), vbox, FALSE, FALSE, 0); + + /* The table that holds the entries */ + entryContainer = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); + + gtk_alignment_set_padding(GTK_ALIGNMENT(entryContainer), + 0, 0, 0, 0); + + gtk_box_pack_start(GTK_BOX(vbox), entryContainer, + FALSE, FALSE, 0); + + table = gtk_table_new(2, 2, FALSE); + gtk_table_set_col_spacings(GTK_TABLE (table), 12); + gtk_table_set_row_spacings(GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(entryContainer), table); + + authData->loginEntry = table_add_entry(table, 0, "Username:", + login, NULL); + authData->passwordEntry = table_add_entry(table, 1, "Password:", + password, NULL); + + gtk_entry_set_visibility(GTK_ENTRY(authData->passwordEntry), FALSE); + +#if USE(GNOMEKEYRING) + rememberBox = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (vbox), rememberBox, + FALSE, FALSE, 0); + + checkButton = gtk_check_button_new_with_label("Remember password"); + if (login && password) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkButton), TRUE); + gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(checkButton))), TRUE); + gtk_box_pack_start (GTK_BOX (rememberBox), checkButton, FALSE, FALSE, 0); + authData->checkButton = checkButton; +#endif + + g_signal_connect(dialog, "response", G_CALLBACK(response_callback), authData); + gtk_widget_show_all(widget); +} + +#if USE(GNOMEKEYRING) +static void find_password_callback(GnomeKeyringResult result, GList* list, WebKitAuthData* authData) +{ + GList* p; + const char* login = NULL; + const char* password = NULL; + + for (p = list; p; p = p->next) { + /* FIXME: support multiple logins/passwords ? */ + GnomeKeyringNetworkPasswordData* data = (GnomeKeyringNetworkPasswordData*)p->data; + login = data->user; + password = data->password; + break; + } + + show_auth_dialog(authData, login, password); +} +#endif + +static void session_authenticate(SoupSession* session, SoupMessage* msg, SoupAuth* auth, gboolean retrying, gpointer user_data) +{ + SoupURI* uri; + WebKitAuthData* authData; + SoupSessionFeature* manager = (SoupSessionFeature*)user_data; + + soup_session_pause_message(session, msg); + /* We need to make sure the message sticks around when pausing it */ + g_object_ref(msg); + + uri = soup_message_get_uri(msg); + authData = g_slice_new(WebKitAuthData); + authData->msg = msg; + authData->auth = auth; + authData->session = session; + authData->manager = manager; + + /* + * If we have gnome-keyring let's try to find the password first in the ring. + * Otherwise just show the dialog straight away + */ +#if USE(GNOMEKEYRING) + gnome_keyring_find_network_password(NULL, + soup_auth_get_realm(auth), + uri->host, + NULL, + uri->scheme, + soup_auth_get_scheme_name(auth), + uri->port, + (GnomeKeyringOperationGetListCallback)find_password_callback, + authData, + NULL); +#else + show_auth_dialog(authData, NULL, NULL); +#endif +} + +static void attach(SoupSessionFeature* manager, SoupSession* session) +{ + g_signal_connect(session, "authenticate", G_CALLBACK(session_authenticate), manager); +} + +static void detach(SoupSessionFeature* manager, SoupSession* session) +{ + g_signal_handlers_disconnect_by_func(session, session_authenticate, manager); +} + + diff --git a/WebKit/gtk/webkit/webkitsoupauthdialog.h b/WebKit/gtk/webkit/webkitsoupauthdialog.h new file mode 100644 index 0000000..2c030b4 --- /dev/null +++ b/WebKit/gtk/webkit/webkitsoupauthdialog.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> +#include <libsoup/soup.h> + +#ifndef WEBKIT_SOUP_AUTH_DIALOG_H +#define WEBKIT_SOUP_AUTH_DIALOG_H 1 + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_SOUP_AUTH_DIALOG (webkit_soup_auth_dialog_get_type ()) +#define WEBKIT_SOUP_AUTH_DIALOG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), WEBKIT_TYPE_SOUP_AUTH_DIALOG, WebKitSoupAuthDialog)) +#define WEBKIT_SOUP_AUTH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_SOUP_AUTH_DIALOG, WebKitSoupAuthDialog)) +#define WEBKIT_IS_SOUP_AUTH_DIALOG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), WEBKIT_TYPE_SOUP_AUTH_DIALOG)) +#define WEBKIT_IS_SOUP_AUTH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_SOUP_AUTH_DIALOG)) +#define WEBKIT_SOUP_AUTH_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_SOUP_AUTH_DIALOG, WebKitSoupAuthDialog)) + +typedef struct { + GObject parent_instance; +} WebKitSoupAuthDialog; + +typedef struct { + GObjectClass parent_class; + + GtkWidget* (*current_toplevel) (WebKitSoupAuthDialog* feature, SoupMessage* message); +} WebKitSoupAuthDialogClass; + +GType webkit_soup_auth_dialog_get_type (void); + +G_END_DECLS + +#endif /* WEBKIT_SOUP_AUTH_DIALOG_H */ diff --git a/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp b/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp index 3899f4b..5c93df0 100644 --- a/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp +++ b/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp @@ -189,11 +189,11 @@ GList* webkit_web_back_forward_list_get_forward_list_with_limit(WebKitWebBackFor backForwardList->forwardListWithLimit(limit, items); for (unsigned i = 0; i < items.size(); i++) { - WebKitWebHistoryItem* webHistoryItem = webkit_web_history_item_new_with_core_item(items[i].get()); - forwardItems = g_list_prepend(forwardItems, g_object_ref(webHistoryItem)); + WebKitWebHistoryItem* webHistoryItem = kit(items[i]); + forwardItems = g_list_prepend(forwardItems, webHistoryItem); } - return g_list_reverse(forwardItems); + return forwardItems; } /** @@ -219,12 +219,13 @@ GList* webkit_web_back_forward_list_get_back_list_with_limit(WebKitWebBackForwar backForwardList->backListWithLimit(limit, items); for (unsigned i = 0; i < items.size(); i++) { - WebKitWebHistoryItem* webHistoryItem = webkit_web_history_item_new_with_core_item(items[i].get()); - backItems = g_list_prepend(backItems, g_object_ref(webHistoryItem)); + WebKitWebHistoryItem* webHistoryItem = kit(items[i]); + backItems = g_list_prepend(backItems, webHistoryItem); } - return g_list_reverse(backItems); + return backItems; } + /** * webkit_web_back_forward_list_get_back_item: * @web_back_forward_list: a #WebBackForwardList @@ -389,6 +390,25 @@ void webkit_web_back_forward_list_set_limit(WebKitWebBackForwardList* webBackFor backForwardList->setCapacity(limit); } +/** + * webkit_web_back_forward_list_add_item: + * @web_back_forward_list: a #WebKitWebBackForwardList + * @history_item: the #WebKitWebHistoryItem to add + * + * Adds the item to the #WebKitWebBackForwardList. + * + * Since: 1.1.1 + */ +void webkit_web_back_forward_list_add_item(WebKitWebBackForwardList *webBackForwardList, WebKitWebHistoryItem *webHistoryItem) +{ + g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList)); + + WebCore::BackForwardList* backForwardList = core(webBackForwardList); + WebCore::HistoryItem* historyItem = core(webHistoryItem); + + backForwardList->addItem(historyItem); +} + } /* end extern "C" */ WebCore::BackForwardList* WebKit::core(WebKitWebBackForwardList* webBackForwardList) diff --git a/WebKit/gtk/webkit/webkitwebbackforwardlist.h b/WebKit/gtk/webkit/webkitwebbackforwardlist.h index fb641f0..a44cbcd 100644 --- a/WebKit/gtk/webkit/webkitwebbackforwardlist.h +++ b/WebKit/gtk/webkit/webkitwebbackforwardlist.h @@ -107,6 +107,9 @@ webkit_web_back_forward_list_get_limit (WebKitWebBackForwardLi WEBKIT_API void webkit_web_back_forward_list_set_limit (WebKitWebBackForwardList *web_back_forward_list, gint limit); +WEBKIT_API void +webkit_web_back_forward_list_add_item (WebKitWebBackForwardList *web_back_forward_list, + WebKitWebHistoryItem *history_item); G_END_DECLS diff --git a/WebKit/gtk/webkit/webkitwebframe.cpp b/WebKit/gtk/webkit/webkitwebframe.cpp index 38e23a4..e2b10b6 100644 --- a/WebKit/gtk/webkit/webkitwebframe.cpp +++ b/WebKit/gtk/webkit/webkitwebframe.cpp @@ -5,6 +5,7 @@ * Copyright (C) 2008 Christian Dywan <christian@imendio.com> * Copyright (C) 2008 Collabora Ltd. * Copyright (C) 2008 Nuanti Ltd. + * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,6 +32,7 @@ #include "AnimationController.h" #include "CString.h" +#include "DocumentLoader.h" #include "FrameLoader.h" #include "FrameLoaderClientGtk.h" #include "FrameTree.h" @@ -43,6 +45,7 @@ #include "RenderTreeAsText.h" #include "JSDOMBinding.h" #include "ScriptController.h" +#include "SubstituteData.h" #include <JavaScriptCore/APICast.h> @@ -373,6 +376,60 @@ WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame) } /** + * webkit_web_frame_load_uri: + * @frame: a #WebKitWebFrame + * @uri: an URI string + * + * Requests loading of the specified URI string. + * + * Since: 1.1.1 + */ +void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri) +{ + g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); + g_return_if_fail(uri); + + Frame* coreFrame = core(frame); + if (!coreFrame) + return; + + coreFrame->loader()->load(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), false); +} + +/** + * webkit_web_frame_load_string: + * @frame: a #WebKitWebFrame + * @content: an URI string + * @mime_type: the MIME type, or %NULL + * @encoding: the encoding, or %NULL + * @base_uri: the base URI for relative locations + * + * Requests loading of the given @content with the specified @mime_type, + * @encoding and @base_uri. + * + * If @mime_type is %NULL, "text/html" is assumed. + * + * If @encoding is %NULL, "UTF-8" is assumed. + * + * Since: 1.1.1 + */ +void webkit_web_frame_load_string(WebKitWebFrame* frame, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri) +{ + g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); + g_return_if_fail(content); + + Frame* coreFrame = core(frame); + if (!coreFrame) + return; + + KURL url(KURL(), baseUri ? String::fromUTF8(baseUri) : ""); + RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content)); + SubstituteData substituteData(sharedBuffer.release(), contentMimeType ? String(contentMimeType) : "text/html", contentEncoding ? String(contentEncoding) : "UTF-8", blankURL(), url); + + coreFrame->loader()->load(ResourceRequest(url), substituteData, false); +} + +/** * webkit_web_frame_load_request: * @frame: a #WebKitWebFrame * @request: a #WebKitNetworkRequest @@ -394,7 +451,7 @@ void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* // TODO: Use the ResourceRequest carried by WebKitNetworkRequest when it is implemented. String string = String::fromUTF8(webkit_network_request_get_uri(request)); - coreFrame->loader()->load(ResourceRequest(KURL(string))); + coreFrame->loader()->load(ResourceRequest(KURL(KURL(), string)), false); } /** @@ -662,4 +719,12 @@ unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame) return controller->numberOfActiveAnimations(); } +gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame) +{ + Frame* coreFrame = core(frame); + DocumentLoader* docLoader = coreFrame->loader()->documentLoader(); + String mimeType = docLoader->responseMIMEType(); + return g_strdup(mimeType.utf8().data()); +} + } diff --git a/WebKit/gtk/webkit/webkitwebframe.h b/WebKit/gtk/webkit/webkitwebframe.h index fcdace6..7e24565 100644 --- a/WebKit/gtk/webkit/webkitwebframe.h +++ b/WebKit/gtk/webkit/webkitwebframe.h @@ -81,6 +81,17 @@ WEBKIT_API WebKitWebFrame* webkit_web_frame_get_parent (WebKitWebFrame *frame); WEBKIT_API void +webkit_web_frame_load_uri (WebKitWebFrame *frame, + const gchar *uri); + +WEBKIT_API void +webkit_web_frame_load_string (WebKitWebFrame *frame, + const gchar *content, + const gchar *mime_type, + const gchar *encoding, + const gchar *base_uri); + +WEBKIT_API void webkit_web_frame_load_request (WebKitWebFrame *frame, WebKitNetworkRequest *request); diff --git a/WebKit/gtk/webkit/webkitwebhistoryitem.cpp b/WebKit/gtk/webkit/webkitwebhistoryitem.cpp index 8cdaa90..42e6a9b 100644 --- a/WebKit/gtk/webkit/webkitwebhistoryitem.cpp +++ b/WebKit/gtk/webkit/webkitwebhistoryitem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Jan Michael C. Alonzo + * Copyright (C) 2008, 2009 Jan Michael C. Alonzo * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,7 +17,6 @@ * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "webkitwebhistoryitem.h" @@ -53,12 +52,14 @@ using namespace WebKit; extern "C" { struct _WebKitWebHistoryItemPrivate { - WTF::RefPtr<WebCore::HistoryItem> historyItem; + WebCore::HistoryItem* historyItem; WebCore::CString title; WebCore::CString alternateTitle; WebCore::CString uri; WebCore::CString originalUri; + + gboolean disposed; }; #define WEBKIT_WEB_HISTORY_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_HISTORY_ITEM, WebKitWebHistoryItemPrivate)) @@ -81,7 +82,7 @@ static void webkit_web_history_item_get_property(GObject* object, guint prop_id, static GHashTable* webkit_history_items() { - static GHashTable* historyItems = g_hash_table_new(g_direct_hash, g_direct_equal); + static GHashTable* historyItems = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref); return historyItems; } @@ -94,27 +95,24 @@ static void webkit_history_item_add(WebKitWebHistoryItem* webHistoryItem, WebCor g_hash_table_insert(table, historyItem, g_object_ref(webHistoryItem)); } -static void webkit_history_item_remove(WebCore::HistoryItem* historyItem) -{ - GHashTable* table = webkit_history_items(); - WebKitWebHistoryItem* webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, historyItem); - - g_return_if_fail(webHistoryItem != NULL); - - g_hash_table_remove(table, historyItem); - g_object_unref(webHistoryItem); -} - static void webkit_web_history_item_dispose(GObject* object) { WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(object); + WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; + WebCore::HistoryItem* item = core(webHistoryItem); - webkit_history_item_remove(core(webHistoryItem)); + if (!priv->disposed) { + GHashTable* table = webkit_history_items(); - /* destroy table if empty */ - GHashTable* table = webkit_history_items(); - if (!g_hash_table_size(table)) - g_hash_table_destroy(table); + g_hash_table_remove(table, item); + item->deref(); + + /* destroy table if empty */ + if (!g_hash_table_size(table)) + g_hash_table_destroy(table); + + priv->disposed = true; + } G_OBJECT_CLASS(webkit_web_history_item_parent_class)->dispose(object); } @@ -270,21 +268,9 @@ static void webkit_web_history_item_get_property(GObject* object, guint prop_id, } /* Helper function to create a new WebHistoryItem instance when needed */ -WebKitWebHistoryItem* webkit_web_history_item_new_with_core_item(WebCore::HistoryItem* item) +WebKitWebHistoryItem* webkit_web_history_item_new_with_core_item(PassRefPtr<WebCore::HistoryItem> historyItem) { - WebKitWebHistoryItem* webHistoryItem = kit(item); - - if (webHistoryItem) - g_object_ref(webHistoryItem); - else { - webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); - WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - - priv->historyItem = item; - webkit_history_item_add(webHistoryItem, priv->historyItem.get()); - } - - return webHistoryItem; + return kit(historyItem); } @@ -300,8 +286,9 @@ WebKitWebHistoryItem* webkit_web_history_item_new() WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - priv->historyItem = WebCore::HistoryItem::create(); - webkit_history_item_add(webHistoryItem, priv->historyItem.get()); + RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); + priv->historyItem = item.release().releaseRef(); + webkit_history_item_add(webHistoryItem, priv->historyItem); return webHistoryItem; } @@ -323,8 +310,9 @@ WebKitWebHistoryItem* webkit_web_history_item_new_with_data(const gchar* uri, co WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - priv->historyItem = WebCore::HistoryItem::create(historyUri, historyTitle, 0); - webkit_history_item_add(webHistoryItem, priv->historyItem.get()); + RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(historyUri, historyTitle, 0); + priv->historyItem = item.release().releaseRef(); + webkit_history_item_add(webHistoryItem, priv->historyItem); return webHistoryItem; } @@ -341,7 +329,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_title(WebKitWebHistoryItem* we WebCore::HistoryItem* item = core(webHistoryItem); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->title = item->title().utf8(); @@ -363,7 +351,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_alternate_title(WebKitWebHisto WebCore::HistoryItem* item = core(webHistoryItem); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->alternateTitle = item->alternateTitle().utf8(); @@ -403,7 +391,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_uri(WebKitWebHistoryItem* webH WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->uri = item->urlString().utf8(); @@ -425,7 +413,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_original_uri(WebKitWebHistoryI WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->originalUri = item->originalURLString().utf8(); @@ -447,31 +435,84 @@ gdouble webkit_web_history_item_get_last_visited_time(WebKitWebHistoryItem* webH WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); - g_return_val_if_fail(item != NULL, 0); + g_return_val_if_fail(item, 0); return item->lastVisitedTime(); } +/* private methods */ + +G_CONST_RETURN gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem* webHistoryItem) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); + + WebCore::HistoryItem* item = core(webHistoryItem); + + g_return_val_if_fail(item, NULL); + + WebCore::CString t = item->target().utf8(); + return g_strdup(t.data()); +} + +gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem* webHistoryItem) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), false); + + WebCore::HistoryItem* item = core(webHistoryItem); + + g_return_val_if_fail(item, false); + + return item->isTargetItem(); +} + +GList* webkit_web_history_item_get_children(WebKitWebHistoryItem* webHistoryItem) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); + + WebCore::HistoryItem* item = core(webHistoryItem); + + g_return_val_if_fail(item, NULL); + + const WebCore::HistoryItemVector& children = item->children(); + if (!children.size()) + return NULL; + + unsigned size = children.size(); + GList* kids = NULL; + for (unsigned i = 0; i < size; ++i) + kids = g_list_prepend(kids, kit(children[i].get())); + + return g_list_reverse(kids); +} + } /* end extern "C" */ WebCore::HistoryItem* WebKit::core(WebKitWebHistoryItem* webHistoryItem) { g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); - WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - WTF::RefPtr<WebCore::HistoryItem> historyItem = priv->historyItem; - - return historyItem ? historyItem.get() : 0; + return webHistoryItem->priv->historyItem; } -WebKitWebHistoryItem* WebKit::kit(WebCore::HistoryItem* historyItem) +WebKitWebHistoryItem* WebKit::kit(PassRefPtr<WebCore::HistoryItem> historyItem) { - g_return_val_if_fail(historyItem != NULL, NULL); + g_return_val_if_fail(historyItem, NULL); + + RefPtr<WebCore::HistoryItem> item = historyItem; WebKitWebHistoryItem* webHistoryItem; GHashTable* table = webkit_history_items(); - webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, historyItem); + webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, item.get()); + + if (!webHistoryItem) { + webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); + WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; + + priv->historyItem = item.release().releaseRef(); + webkit_history_item_add(webHistoryItem, priv->historyItem); + } + return webHistoryItem; } diff --git a/WebKit/gtk/webkit/webkitwebinspector.cpp b/WebKit/gtk/webkit/webkitwebinspector.cpp index b8f8d9e..8e1c8c0 100644 --- a/WebKit/gtk/webkit/webkitwebinspector.cpp +++ b/WebKit/gtk/webkit/webkitwebinspector.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Gustavo Noronha Silva - * Copyright (C) 2008 Holger Hans Peter Freyther + * Copyright (C) 2008, 2009 Holger Hans Peter Freyther * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -75,12 +75,13 @@ enum { PROP_WEB_VIEW, PROP_INSPECTED_URI, + PROP_JAVASCRIPT_PROFILING_ENABLED }; G_DEFINE_TYPE(WebKitWebInspector, webkit_web_inspector, G_TYPE_OBJECT) struct _WebKitWebInspectorPrivate { - InspectorClient* inspectorClient; + WebCore::Page* page; WebKitWebView* inspector_view; gchar* inspected_uri; }; @@ -274,6 +275,23 @@ static void webkit_web_inspector_class_init(WebKitWebInspectorClass* klass) NULL, WEBKIT_PARAM_READABLE)); + /** + * WebKitWebInspector:javascript-profiling-enabled + * + * This is enabling JavaScript profiling in the Inspector. This means + * that Console.profiles will return the profiles. + * + * Since: 1.1.1 + */ + g_object_class_install_property(gobject_class, + PROP_JAVASCRIPT_PROFILING_ENABLED, + g_param_spec_boolean( + "javascript-profiling-enabled", + "Enable JavaScript profiling", + "Profile the executed JavaScript.", + FALSE, + WEBKIT_PARAM_READWRITE)); + g_type_class_add_private(klass, sizeof(WebKitWebInspectorPrivate)); } @@ -298,7 +316,19 @@ static void webkit_web_inspector_finalize(GObject* object) static void webkit_web_inspector_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { + WebKitWebInspector* web_inspector = WEBKIT_WEB_INSPECTOR(object); + WebKitWebInspectorPrivate* priv = web_inspector->priv; + switch(prop_id) { + case PROP_JAVASCRIPT_PROFILING_ENABLED: { + bool enabled = g_value_get_boolean(value); + WebCore::InspectorController* controller = priv->page->inspectorController(); + if (enabled) + controller->enableProfiler(); + else + controller->disableProfiler(); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -317,6 +347,9 @@ static void webkit_web_inspector_get_property(GObject* object, guint prop_id, GV case PROP_INSPECTED_URI: g_value_set_string(value, priv->inspected_uri); break; + case PROP_JAVASCRIPT_PROFILING_ENABLED: + g_value_set_boolean(value, priv->page->inspectorController()->profilerEnabled()); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -388,11 +421,11 @@ const gchar* webkit_web_inspector_get_inspected_uri(WebKitWebInspector *web_insp } void -webkit_web_inspector_set_inspector_client(WebKitWebInspector* web_inspector, WebKit::InspectorClient* inspectorClient) +webkit_web_inspector_set_inspector_client(WebKitWebInspector* web_inspector, WebCore::Page* page) { WebKitWebInspectorPrivate* priv = web_inspector->priv; - priv->inspectorClient = inspectorClient; + priv->page = page; } } diff --git a/WebKit/gtk/webkit/webkitwebsettings.cpp b/WebKit/gtk/webkit/webkitwebsettings.cpp index aa38c6c..d31ec2f 100644 --- a/WebKit/gtk/webkit/webkitwebsettings.cpp +++ b/WebKit/gtk/webkit/webkitwebsettings.cpp @@ -74,6 +74,7 @@ struct _WebKitWebSettingsPrivate { gchar* user_stylesheet_uri; gfloat zoom_step; gboolean enable_developer_extras; + gboolean enable_private_browsing; }; #define WEBKIT_WEB_SETTINGS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_SETTINGS, WebKitWebSettingsPrivate)) @@ -101,7 +102,8 @@ enum { PROP_RESIZABLE_TEXT_AREAS, PROP_USER_STYLESHEET_URI, PROP_ZOOM_STEP, - PROP_ENABLE_DEVELOPER_EXTRAS + PROP_ENABLE_DEVELOPER_EXTRAS, + PROP_ENABLE_PRIVATE_BROWSING }; static void webkit_web_settings_finalize(GObject* object); @@ -335,6 +337,22 @@ static void webkit_web_settings_class_init(WebKitWebSettingsClass* klass) FALSE, flags)); + /** + * WebKitWebSettings:enable-private-browsing: + * + * Whether to enable private browsing mode. + * + * Since 1.1.2 + */ + g_object_class_install_property(gobject_class, + PROP_ENABLE_PRIVATE_BROWSING, + g_param_spec_boolean( + "enable-private-browsing", + "Enable Private Browsing", + "Enables private browsing mode", + FALSE, + flags)); + g_type_class_add_private(klass, sizeof(WebKitWebSettingsPrivate)); } @@ -437,6 +455,9 @@ static void webkit_web_settings_set_property(GObject* object, guint prop_id, con case PROP_ENABLE_DEVELOPER_EXTRAS: priv->enable_developer_extras = g_value_get_boolean(value); break; + case PROP_ENABLE_PRIVATE_BROWSING: + priv->enable_private_browsing = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -512,6 +533,9 @@ static void webkit_web_settings_get_property(GObject* object, guint prop_id, GVa case PROP_ENABLE_DEVELOPER_EXTRAS: g_value_set_boolean(value, priv->enable_developer_extras); break; + case PROP_ENABLE_PRIVATE_BROWSING: + g_value_set_boolean(value, priv->enable_private_browsing); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -563,6 +587,7 @@ WebKitWebSettings* webkit_web_settings_copy(WebKitWebSettings* web_settings) "user-stylesheet-uri", priv->user_stylesheet_uri, "zoom-step", priv->zoom_step, "enable-developer-extras", priv->enable_developer_extras, + "enable-private-browsing", priv->enable_private_browsing, NULL)); return copy; diff --git a/WebKit/gtk/webkit/webkitwebview.cpp b/WebKit/gtk/webkit/webkitwebview.cpp index 0ea6ed5..d6a0d54 100644 --- a/WebKit/gtk/webkit/webkitwebview.cpp +++ b/WebKit/gtk/webkit/webkitwebview.cpp @@ -1,12 +1,13 @@ /* * Copyright (C) 2007, 2008 Holger Hans Peter Freyther - * Copyright (C) 2007, 2008 Christian Dywan <christian@imendio.com> + * Copyright (C) 2007, 2008, 2009 Christian Dywan <christian@imendio.com> * Copyright (C) 2007 Xan Lopez <xan@gnome.org> * Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com> * Copyright (C) 2008 Jan Alonzo <jmalonzo@unpluggable.com> * Copyright (C) 2008 Gustavo Noronha Silva <gns@gnome.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +26,7 @@ #include "config.h" +#include "webkitdownload.h" #include "webkitwebview.h" #include "webkitenumtypes.h" #include "webkitmarshal.h" @@ -43,6 +45,7 @@ #include "ContextMenuController.h" #include "Cursor.h" #include "Document.h" +#include "DocumentLoader.h" #include "DragClientGtk.h" #include "Editor.h" #include "EditorClientGtk.h" @@ -56,13 +59,12 @@ #include "InspectorClientGtk.h" #include "FrameLoader.h" #include "FrameView.h" -#include "Editor.h" #include "PasteboardHelper.h" #include "PlatformKeyboardEvent.h" #include "PlatformWheelEvent.h" +#include "ResourceHandle.h" #include "ScriptValue.h" #include "Scrollbar.h" -#include "SubstituteData.h" #include <wtf/GOwnPtr.h> #include <gdk/gdkkeysyms.h> @@ -110,6 +112,7 @@ extern "C" { enum { /* normal signals */ NAVIGATION_REQUESTED, + NEW_WINDOW_POLICY_DECISION_REQUESTED, NAVIGATION_POLICY_DECISION_REQUESTED, MIME_TYPE_POLICY_DECISION_REQUESTED, CREATE_WEB_VIEW, @@ -133,12 +136,15 @@ enum { COPY_CLIPBOARD, PASTE_CLIPBOARD, CUT_CLIPBOARD, + DOWNLOAD_REQUESTED, LAST_SIGNAL }; enum { PROP_0, + PROP_TITLE, + PROP_URI, PROP_COPY_TARGET_LIST, PROP_PASTE_TARGET_LIST, PROP_EDITABLE, @@ -147,7 +153,9 @@ enum { PROP_WINDOW_FEATURES, PROP_TRANSPARENT, PROP_ZOOM_LEVEL, - PROP_FULL_CONTENT_ZOOM + PROP_FULL_CONTENT_ZOOM, + PROP_ENCODING, + PROP_CUSTOM_ENCODING }; static guint webkit_web_view_signals[LAST_SIGNAL] = { 0, }; @@ -276,6 +284,12 @@ static void webkit_web_view_get_property(GObject* object, guint prop_id, GValue* WebKitWebView* webView = WEBKIT_WEB_VIEW(object); switch(prop_id) { + case PROP_TITLE: + g_value_set_string(value, webkit_web_view_get_title(webView)); + break; + case PROP_URI: + g_value_set_string(value, webkit_web_view_get_uri(webView)); + break; #if GTK_CHECK_VERSION(2,10,0) case PROP_COPY_TARGET_LIST: g_value_set_boxed(value, webkit_web_view_get_copy_target_list(webView)); @@ -305,6 +319,12 @@ static void webkit_web_view_get_property(GObject* object, guint prop_id, GValue* case PROP_FULL_CONTENT_ZOOM: g_value_set_boolean(value, webkit_web_view_get_full_content_zoom(webView)); break; + case PROP_ENCODING: + g_value_set_string(value, webkit_web_view_get_encoding(webView)); + break; + case PROP_CUSTOM_ENCODING: + g_value_set_string(value, webkit_web_view_get_custom_encoding(webView)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -333,6 +353,9 @@ static void webkit_web_view_set_property(GObject* object, guint prop_id, const G case PROP_FULL_CONTENT_ZOOM: webkit_web_view_set_full_content_zoom(webView, g_value_get_boolean(value)); break; + case PROP_CUSTOM_ENCODING: + webkit_web_view_set_custom_encoding(webView, g_value_get_string(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -436,11 +459,23 @@ static gboolean webkit_web_view_key_press_event(GtkWidget* widget, GdkEventKey* case GDK_Left: view->scrollBy(IntSize(-cScrollbarPixelsPerLineStep, 0)); return TRUE; + case GDK_space: + if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) + view->scrollBy(IntSize(0, -view->visibleHeight())); + else + view->scrollBy(IntSize(0, view->visibleHeight())); + return TRUE; + case GDK_Page_Up: + view->scrollBy(IntSize(0, -view->visibleHeight())); + return TRUE; + case GDK_Page_Down: + view->scrollBy(IntSize(0, view->visibleHeight())); + return TRUE; case GDK_Home: - frame->selection()->modify(alteration, SelectionController::BACKWARD, DocumentBoundary, true); + view->scrollBy(IntSize(0, -view->contentsHeight())); return TRUE; case GDK_End: - frame->selection()->modify(alteration, SelectionController::FORWARD, DocumentBoundary, true); + view->scrollBy(IntSize(0, view->contentsHeight())); return TRUE; } @@ -496,10 +531,17 @@ static gboolean webkit_web_view_button_release_event(GtkWidget* widget, GdkEvent } Frame* mainFrame = core(webView)->mainFrame(); - if (!mainFrame->view()) - return FALSE; + if (mainFrame->view()) + mainFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event)); + + /* We always return FALSE here because WebKit can, for the same click, decide + * to not handle press-event but handle release-event, which can totally confuse + * some GTK+ containers when there are no other events in between. This way we + * guarantee that this case never happens, and that if press-event goes through + * release-event also goes through. + */ - return mainFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event)); + return FALSE; } static gboolean webkit_web_view_motion_event(GtkWidget* widget, GdkEventMotion* event) @@ -536,7 +578,7 @@ static void webkit_web_view_size_allocate(GtkWidget* widget, GtkAllocation* allo return; frame->view()->resize(allocation->width, allocation->height); - frame->forceLayout(); + frame->view()->forceLayout(); frame->view()->adjustViewSize(); } @@ -816,6 +858,8 @@ static void webkit_web_view_dispose(GObject* object) WebKitWebView* webView = WEBKIT_WEB_VIEW(object); WebKitWebViewPrivate* priv = webView->priv; + priv->disposing = TRUE; + if (priv->corePage) { webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object)); @@ -864,6 +908,17 @@ static void webkit_web_view_dispose(GObject* object) G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object); } +static void webkit_web_view_finalize(GObject* object) +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(object); + WebKitWebViewPrivate* priv = webView->priv; + + g_free(priv->encoding); + g_free(priv->customEncoding); + + G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object); +} + static gboolean webkit_create_web_view_request_handled(GSignalInvocationHint* ihint, GValue* returnAccu, const GValue* handlerReturn, gpointer dummy) { gpointer newWebView = g_value_get_object(handlerReturn); @@ -998,6 +1053,45 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) WEBKIT_TYPE_NETWORK_REQUEST); /** + * WebKitWebView::new-window-policy-decision-requested: + * @web_view: the object on which the signal is emitted + * @frame: the #WebKitWebFrame that required the navigation + * @request: a #WebKitNetworkRequest + * @navigation_action: a #WebKitWebNavigation + * @policy_decision: a #WebKitWebPolicyDecision + * @return: TRUE if the signal will be handled, FALSE to have the + * default behavior apply + * + * Emitted when @frame requests opening a new window. With this + * signal the browser can use the context of the request to decide + * about the new window. If the request is not handled the default + * behavior is to allow opening the new window to load the url, + * which will cause a create-web-view signal emission where the + * browser handles the new window action but without information + * of the context that caused the navigation. The following + * navigation-policy-decision-requested emissions will load the + * page after the creation of the new window just with the + * information of this new navigation context, without any + * information about the action that made this new window to be + * opened. + * + * Since: 1.1.4 + */ + webkit_web_view_signals[NEW_WINDOW_POLICY_DECISION_REQUESTED] = + g_signal_new("new-window-policy-decision-requested", + G_TYPE_FROM_CLASS(webViewClass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + g_signal_accumulator_true_handled, + NULL, + webkit_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT_OBJECT, + G_TYPE_BOOLEAN, 4, + WEBKIT_TYPE_WEB_FRAME, + WEBKIT_TYPE_NETWORK_REQUEST, + WEBKIT_TYPE_WEB_NAVIGATION_ACTION, + WEBKIT_TYPE_WEB_POLICY_DECISION); + + /** * WebKitWebView::navigation-policy-decision-requested: * @web_view: the object on which the signal is emitted * @frame: the #WebKitWebFrame that required the navigation @@ -1085,6 +1179,34 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_TYPE_POINTER); /** + * WebKitWebView::download-requested: + * @web_view: the object on which the signal is emitted + * @download: a #WebKitDownload object that lets you control the + * download process + * @return: %TRUE if the download should be performed, %FALSE to cancel it. + * + * A new Download is being requested. By default, if the signal is + * not handled, the download is cancelled. Notice that while + * handling this signal you must set the target URI using + * webkit_download_set_target_uri(). + * + * If you intend to handle downloads yourself rather than using + * the #WebKitDownload helper object you must handle this signal, + * and return %FALSE. + * + * Since: 1.1.2 + */ + webkit_web_view_signals[DOWNLOAD_REQUESTED] = g_signal_new("download-requested", + G_TYPE_FROM_CLASS(webViewClass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + g_signal_accumulator_true_handled, + NULL, + webkit_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, 1, + G_TYPE_OBJECT); + + /** * WebKitWebView::load-started: * @web_view: the object on which the signal is emitted * @frame: the frame going to do the load @@ -1151,6 +1273,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * @title: the new title * * When a #WebKitWebFrame changes the document title this signal is emitted. + * + * Deprecated: 1.1.4: Use "notify::title" instead. */ webkit_web_view_signals[TITLE_CHANGED] = g_signal_new("title-changed", G_TYPE_FROM_CLASS(webViewClass), @@ -1284,9 +1408,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm), g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__OBJECT_STRING_BOOLEAN, + webkit_marshal_BOOLEAN__OBJECT_STRING_POINTER, G_TYPE_BOOLEAN, 3, - WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_BOOLEAN); + WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_POINTER); /** * WebKitWebView::script-prompt: @@ -1396,6 +1520,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) GObjectClass* objectClass = G_OBJECT_CLASS(webViewClass); objectClass->dispose = webkit_web_view_dispose; + objectClass->finalize = webkit_web_view_finalize; objectClass->get_property = webkit_web_view_get_property; objectClass->set_property = webkit_web_view_set_property; @@ -1461,6 +1586,34 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * properties */ + /** + * WebKitWebView:title: + * + * Returns the @web_view's document title. + * + * Since: 1.1.4 + */ + g_object_class_install_property(objectClass, PROP_TITLE, + g_param_spec_string("title", + "Title", + "Returns the @web_view's document title", + NULL, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitWebView:uri: + * + * Returns the current URI of the contents displayed by the @web_view. + * + * Since: 1.1.4 + */ + g_object_class_install_property(objectClass, PROP_URI, + g_param_spec_string("uri", + "URI", + "Returns the current URI of the contents displayed by the @web_view", + NULL, + WEBKIT_PARAM_READABLE)); + #if GTK_CHECK_VERSION(2,10,0) /** * WebKitWebView:copy-target-list: @@ -1570,6 +1723,34 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) FALSE, WEBKIT_PARAM_READWRITE)); + /** + * WebKitWebView:encoding: + * + * The default encoding of the web view. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_ENCODING, + g_param_spec_string("encoding", + "Encoding", + "The default encoding of the web view", + NULL, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitWebView:custom-encoding: + * + * The custom encoding of the web view. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_CUSTOM_ENCODING, + g_param_spec_string("custom-encoding", + "Custom Encoding", + "The custom encoding of the web view", + NULL, + WEBKIT_PARAM_READWRITE)); + g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate)); } @@ -1625,7 +1806,9 @@ static void webkit_web_view_update_settings(WebKitWebView* webView) Settings* settings = core(webView)->settings(); gchar* defaultEncoding, *cursiveFontFamily, *defaultFontFamily, *fantasyFontFamily, *monospaceFontFamily, *sansSerifFontFamily, *serifFontFamily, *userStylesheetUri; - gboolean autoLoadImages, autoShrinkImages, printBackgrounds, enableScripts, enablePlugins, enableDeveloperExtras, resizableTextAreas; + gboolean autoLoadImages, autoShrinkImages, printBackgrounds, + enableScripts, enablePlugins, enableDeveloperExtras, resizableTextAreas, + enablePrivateBrowsing; g_object_get(webSettings, "default-encoding", &defaultEncoding, @@ -1643,6 +1826,7 @@ static void webkit_web_view_update_settings(WebKitWebView* webView) "resizable-text-areas", &resizableTextAreas, "user-stylesheet-uri", &userStylesheetUri, "enable-developer-extras", &enableDeveloperExtras, + "enable-private-browsing", &enablePrivateBrowsing, NULL); settings->setDefaultTextEncodingName(defaultEncoding); @@ -1658,8 +1842,9 @@ static void webkit_web_view_update_settings(WebKitWebView* webView) settings->setJavaScriptEnabled(enableScripts); settings->setPluginsEnabled(enablePlugins); settings->setTextAreasAreResizable(resizableTextAreas); - settings->setUserStyleSheetLocation(KURL(userStylesheetUri)); + settings->setUserStyleSheetLocation(KURL(KURL(), userStylesheetUri)); settings->setDeveloperExtrasEnabled(enableDeveloperExtras); + settings->setPrivateBrowsingEnabled(enablePrivateBrowsing); g_free(defaultEncoding); g_free(cursiveFontFamily); @@ -1725,9 +1910,11 @@ static void webkit_web_view_settings_notify(WebKitWebSettings* webSettings, GPar else if (name == g_intern_string("resizable-text-areas")) settings->setTextAreasAreResizable(g_value_get_boolean(&value)); else if (name == g_intern_string("user-stylesheet-uri")) - settings->setUserStyleSheetLocation(KURL(g_value_get_string(&value))); + settings->setUserStyleSheetLocation(KURL(KURL(), g_value_get_string(&value))); else if (name == g_intern_string("enable-developer-extras")) settings->setDeveloperExtrasEnabled(g_value_get_boolean(&value)); + else if (name == g_intern_string("enable-private-browsing")) + settings->setPrivateBrowsingEnabled(g_value_get_boolean(&value)); else if (!g_object_class_find_property(G_OBJECT_GET_CLASS(webSettings), name)) g_warning("Unexpected setting '%s'", name); g_value_unset(&value); @@ -1746,20 +1933,13 @@ static void webkit_web_view_init(WebKitWebView* webView) // We also add a simple wrapper class to provide the public // interface for the Web Inspector. priv->webInspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)); - webkit_web_inspector_set_inspector_client(priv->webInspector, inspectorClient); + webkit_web_inspector_set_inspector_client(priv->webInspector, priv->corePage); priv->horizontalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); priv->verticalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); -#if GLIB_CHECK_VERSION(2,10,0) g_object_ref_sink(priv->horizontalAdjustment); g_object_ref_sink(priv->verticalAdjustment); -#else - g_object_ref(priv->horizontalAdjustment); - gtk_object_sink(GTK_OBJECT(priv->horizontalAdjustment)); - g_object_ref(priv->verticalAdjustment); - gtk_object_sink(GTK_OBJECT(priv->verticalAdjustment)); -#endif GTK_WIDGET_SET_FLAGS(webView, GTK_CAN_FOCUS); priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView)); @@ -1890,6 +2070,42 @@ WebKitWebWindowFeatures* webkit_web_view_get_window_features(WebKitWebView* webV } /** + * webkit_web_view_get_title: + * @web_view: a #WebKitWebView + * + * Returns the @web_view's document title + * + * Since: 1.1.4 + * + * Return value: the title of @web_view + */ +G_CONST_RETURN gchar* webkit_web_view_get_title(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + WebKitWebViewPrivate* priv = webView->priv; + return priv->mainFrame->priv->title; +} + +/** + * webkit_web_view_get_uri: + * @web_view: a #WebKitWebView + * + * Returns the current URI of the contents displayed by the @web_view + * + * Since: 1.1.4 + * + * Return value: the URI of @web_view + */ +G_CONST_RETURN gchar* webkit_web_view_get_uri(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + WebKitWebViewPrivate* priv = webView->priv; + return priv->mainFrame->priv->uri; +} + +/** * webkit_web_view_set_maintains_back_forward_list: * @web_view: a #WebKitWebView * @flag: to tell the view to maintain a back or forward list @@ -2048,13 +2264,29 @@ gboolean webkit_web_view_can_go_forward(WebKitWebView* webView) return TRUE; } +/** + * webkit_web_view_open: + * @web_view: a #WebKitWebView + * @uri: an URI + * + * Requests loading of the specified URI string. + * + * Deprecated: 1.1.1: Use webkit_web_view_load_uri() instead. + */ void webkit_web_view_open(WebKitWebView* webView, const gchar* uri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); g_return_if_fail(uri); - Frame* frame = core(webView)->mainFrame(); - frame->loader()->load(ResourceRequest(KURL(String::fromUTF8(uri)))); + // We used to support local paths, unlike the newer + // function webkit_web_view_load_uri + if (g_path_is_absolute(uri)) { + gchar* fileUri = g_strdup_printf("file://%s", uri); + webkit_web_view_load_uri(webView, fileUri); + g_free(fileUri); + } + else + webkit_web_view_load_uri(webView, uri); } void webkit_web_view_reload(WebKitWebView* webView) @@ -2079,20 +2311,57 @@ void webkit_web_view_reload_bypass_cache(WebKitWebView* webView) core(webView)->mainFrame()->loader()->reload(true); } -void webkit_web_view_load_string(WebKitWebView* webView, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri) +/** + * webkit_web_view_load_uri: + * @web_view: a #WebKitWebView + * @uri: an URI string + * + * Requests loading of the specified URI string. + * + * Since: 1.1.1 + */ +void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - g_return_if_fail(content); + g_return_if_fail(uri); - Frame* frame = core(webView)->mainFrame(); + WebKitWebFrame* frame = webView->priv->mainFrame; + webkit_web_frame_load_uri(frame, uri); +} - KURL url(baseUri ? String::fromUTF8(baseUri) : ""); - RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content)); - SubstituteData substituteData(sharedBuffer.release(), contentMimeType ? String(contentMimeType) : "text/html", contentEncoding ? String(contentEncoding) : "UTF-8", KURL("about:blank"), url); +/** ++ * webkit_web_view_load_string: ++ * @web_view: a #WebKitWebView ++ * @content: an URI string ++ * @mime_type: the MIME type, or %NULL ++ * @encoding: the encoding, or %NULL ++ * @base_uri: the base URI for relative locations ++ * ++ * Requests loading of the given @content with the specified @mime_type, ++ * @encoding and @base_uri. ++ * ++ * If @mime_type is %NULL, "text/html" is assumed. ++ * ++ * If @encoding is %NULL, "UTF-8" is assumed. ++ */ +void webkit_web_view_load_string(WebKitWebView* webView, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseUri) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(content); - frame->loader()->load(ResourceRequest(url), substituteData); + WebKitWebFrame* frame = webView->priv->mainFrame; + webkit_web_frame_load_string(frame, content, mimeType, encoding, baseUri); } - +/** + * webkit_web_view_load_html_string: + * @web_view: a #WebKitWebView + * @content: an URI string + * @base_uri: the base URI for relative locations + * + * Requests loading of the given @content with the specified @base_uri. + * + * Deprecated: 1.1.1: Use webkit_web_view_load_string() instead. + */ void webkit_web_view_load_html_string(WebKitWebView* webView, const gchar* content, const gchar* baseUri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); @@ -2101,6 +2370,28 @@ void webkit_web_view_load_html_string(WebKitWebView* webView, const gchar* conte webkit_web_view_load_string(webView, content, NULL, NULL, baseUri); } +/** + * webkit_web_view_load_request: + * @web_view: a #WebKitWebView + * @request: a #WebKitNetworkRequest + * + * Requests loading of the specified asynchronous client request. + * + * Creates a provisional data source that will transition to a committed data + * source once any data has been received. Use webkit_web_view_stop_loading() to + * stop the load. + * + * Since: 1.1.1 + */ +void webkit_web_view_load_request(WebKitWebView* webView, WebKitNetworkRequest* request) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request)); + + WebKitWebFrame* frame = webView->priv->mainFrame; + webkit_web_frame_load_request(frame, request); +} + void webkit_web_view_stop_loading(WebKitWebView* webView) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); @@ -2673,4 +2964,89 @@ void webkit_web_view_set_full_content_zoom(WebKitWebView* webView, gboolean zoom g_object_notify(G_OBJECT(webView), "full-content-zoom"); } +/** + * webkit_get_default_session: + * + * Retrieves the default #SoupSession used by all web views. + * Note that the session features are added by WebKit on demand, + * so if you insert your own #SoupCookieJar before any network + * traffic occurs, WebKit will use it instead of the default. + * + * Return value: the default #SoupSession + * + * Since: 1.1.1 + */ +SoupSession* webkit_get_default_session () +{ + return ResourceHandle::defaultSession(); +} + +} + +/** + * webkit_web_view_get_encoding: + * @web_view: a #WebKitWebView + * + * Returns the default encoding of the #WebKitWebView. + * + * Return value: the default encoding + * + * Since: 1.1.1 + */ +const gchar* webkit_web_view_get_encoding(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + String encoding = core(webView)->mainFrame()->loader()->encoding(); + + if (!encoding.isEmpty()) { + WebKitWebViewPrivate* priv = webView->priv; + g_free(priv->encoding); + priv->encoding = g_strdup(encoding.utf8().data()); + return priv->encoding; + } else + return NULL; +} + +/** + * webkit_web_view_set_custom_encoding: + * @web_view: a #WebKitWebView + * @encoding: the new encoding, or %NULL to restore the default encoding + * + * Sets the current #WebKitWebView encoding, without modifying the default one, + * and reloads the page. + * + * Since: 1.1.1 + */ +void webkit_web_view_set_custom_encoding(WebKitWebView* webView, const char* encoding) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + + core(webView)->mainFrame()->loader()->reloadWithOverrideEncoding(String::fromUTF8(encoding)); +} + +/** + * webkit_web_view_get_custom_encoding: + * @web_view: a #WebKitWebView + * + * Returns the current encoding of the #WebKitWebView, not the default-encoding + * of WebKitWebSettings. + * + * Return value: a string containing the current custom encoding for @web_view, or %NULL if there's none set. + * + * Since: 1.1.1 + */ +const char* webkit_web_view_get_custom_encoding(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + String overrideEncoding = core(webView)->mainFrame()->loader()->documentLoader()->overrideEncoding(); + + if (!overrideEncoding.isEmpty()) { + WebKitWebViewPrivate* priv = webView->priv; + g_free (priv->customEncoding); + priv->customEncoding = g_strdup(overrideEncoding.utf8().data()); + return priv->customEncoding; + } else + return NULL; } diff --git a/WebKit/gtk/webkit/webkitwebview.h b/WebKit/gtk/webkit/webkitwebview.h index 2bb8c61..1455a79 100644 --- a/WebKit/gtk/webkit/webkitwebview.h +++ b/WebKit/gtk/webkit/webkitwebview.h @@ -23,6 +23,7 @@ #define WEBKIT_WEB_VIEW_H #include <gtk/gtk.h> +#include <libsoup/soup.h> #include <JavaScriptCore/JSBase.h> #include <webkit/webkitdefines.h> @@ -49,8 +50,8 @@ typedef enum { typedef enum { - WEBKIT_WEB_VIEW_TARGET_INFO_HTML = - 1, - WEBKIT_WEB_VIEW_TARGET_INFO_TEXT = - 2 + WEBKIT_WEB_VIEW_TARGET_INFO_HTML, + WEBKIT_WEB_VIEW_TARGET_INFO_TEXT } WebKitWebViewTargetInfo; struct _WebKitWebView { @@ -126,6 +127,12 @@ webkit_web_view_get_type (void); WEBKIT_API GtkWidget * webkit_web_view_new (void); +WEBKIT_API G_CONST_RETURN gchar * +webkit_web_view_get_title (WebKitWebView *web_view); + +WEBKIT_API G_CONST_RETURN gchar * +webkit_web_view_get_uri (WebKitWebView *web_view); + WEBKIT_API void webkit_web_view_set_maintains_back_forward_list (WebKitWebView *web_view, gboolean flag); @@ -171,10 +178,14 @@ WEBKIT_API void webkit_web_view_reload_bypass_cache (WebKitWebView *web_view); WEBKIT_API void +webkit_web_view_load_uri (WebKitWebView *web_view, + const gchar *uri); + +WEBKIT_API void webkit_web_view_load_string (WebKitWebView *web_view, const gchar *content, - const gchar *content_mime_type, - const gchar *content_encoding, + const gchar *mime_type, + const gchar *encoding, const gchar *base_uri); WEBKIT_API void @@ -182,6 +193,10 @@ webkit_web_view_load_html_string (WebKitWebView *web_view, const gchar *content, const gchar *base_uri); +WEBKIT_API void +webkit_web_view_load_request (WebKitWebView *web_view, + WebKitNetworkRequest *request); + WEBKIT_API gboolean webkit_web_view_search_text (WebKitWebView *web_view, const gchar *text, @@ -296,6 +311,19 @@ WEBKIT_API void webkit_web_view_set_full_content_zoom (WebKitWebView *web_view, gboolean full_content_zoom); +WEBKIT_API SoupSession* +webkit_get_default_session (void); + +WEBKIT_API const gchar* +webkit_web_view_get_encoding (WebKitWebView * webView); + +WEBKIT_API void +webkit_web_view_set_custom_encoding (WebKitWebView * webView, + const gchar * encoding); + +WEBKIT_API const char* +webkit_web_view_get_custom_encoding (WebKitWebView * webView); + G_END_DECLS #endif |