| /* |
| * Copyright (C) 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 |
| * 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 "webkitwebdatasource.h" |
| |
| #include "ArchiveResource.h" |
| #include "DocumentLoaderGtk.h" |
| #include "FrameLoaderClientGtk.h" |
| #include "FrameLoader.h" |
| #include "KURL.h" |
| #include "PlatformString.h" |
| #include "ResourceRequest.h" |
| #include "runtime/InitializeThreading.h" |
| #include "SharedBuffer.h" |
| #include "SubstituteData.h" |
| #include "webkitwebresource.h" |
| #include "webkitprivate.h" |
| #include "wtf/Assertions.h" |
| |
| #include <glib.h> |
| |
| /** |
| * SECTION:webkitwebdatasource |
| * @short_description: Encapsulates the content to be displayed in a #WebKitWebFrame. |
| * @see_also: #WebKitWebFrame |
| * |
| * Data source encapsulates the content of a #WebKitWebFrame. A |
| * #WebKitWebFrame has a main resource and subresources and the data source |
| * provides access to these resources. When a request gets loaded initially, |
| * it is set to a provisional state. The application can request for the |
| * request that initiated the load by asking for the provisional data source |
| * and invoking the webkit_web_data_source_get_initial_request method of |
| * #WebKitWebDataSource. This data source may not have enough data and some |
| * methods may return empty values. To get a "full" data source with the data |
| * and resources loaded, you need to get the non-provisional data source |
| * through #WebKitWebFrame's webkit_web_frame_get_data_source method. This |
| * data source will have the data after everything was loaded. Make sure that |
| * the data source was finished loading before using any of its methods. You |
| * can do this via webkit_web_data_source_is_loading. |
| */ |
| |
| using namespace WebCore; |
| using namespace WebKit; |
| |
| struct _WebKitWebDataSourcePrivate { |
| WebKit::DocumentLoader* loader; |
| |
| WebKitNetworkRequest* initialRequest; |
| WebKitNetworkRequest* networkRequest; |
| WebKitWebResource* mainresource; |
| |
| GString* data; |
| |
| gchar* textEncoding; |
| gchar* unreachableURL; |
| }; |
| |
| #define WEBKIT_WEB_DATA_SOURCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_DATA_SOURCE, WebKitWebDataSourcePrivate)) |
| |
| G_DEFINE_TYPE(WebKitWebDataSource, webkit_web_data_source, G_TYPE_OBJECT); |
| |
| static void webkit_web_data_source_dispose(GObject* object) |
| { |
| WebKitWebDataSource* webDataSource = WEBKIT_WEB_DATA_SOURCE(object); |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| |
| ASSERT(priv->loader); |
| ASSERT(!priv->loader->isLoading()); |
| priv->loader->detachDataSource(); |
| priv->loader->deref(); |
| |
| if (priv->initialRequest) { |
| g_object_unref(priv->initialRequest); |
| priv->initialRequest = NULL; |
| } |
| |
| if (priv->networkRequest) { |
| g_object_unref(priv->networkRequest); |
| priv->networkRequest = NULL; |
| } |
| |
| if (priv->mainresource) { |
| g_object_unref(priv->mainresource); |
| priv->mainresource = NULL; |
| } |
| |
| G_OBJECT_CLASS(webkit_web_data_source_parent_class)->dispose(object); |
| } |
| |
| static void webkit_web_data_source_finalize(GObject* object) |
| { |
| WebKitWebDataSource* dataSource = WEBKIT_WEB_DATA_SOURCE(object); |
| WebKitWebDataSourcePrivate* priv = dataSource->priv; |
| |
| g_free(priv->unreachableURL); |
| g_free(priv->textEncoding); |
| |
| if (priv->data) { |
| g_string_free(priv->data, TRUE); |
| priv->data = NULL; |
| } |
| |
| G_OBJECT_CLASS(webkit_web_data_source_parent_class)->finalize(object); |
| } |
| |
| static void webkit_web_data_source_class_init(WebKitWebDataSourceClass* klass) |
| { |
| GObjectClass* gobject_class = G_OBJECT_CLASS(klass); |
| gobject_class->dispose = webkit_web_data_source_dispose; |
| gobject_class->finalize = webkit_web_data_source_finalize; |
| |
| webkit_init(); |
| |
| g_type_class_add_private(gobject_class, sizeof(WebKitWebDataSourcePrivate)); |
| } |
| |
| static void webkit_web_data_source_init(WebKitWebDataSource* webDataSource) |
| { |
| webDataSource->priv = WEBKIT_WEB_DATA_SOURCE_GET_PRIVATE(webDataSource); |
| } |
| |
| WebKitWebDataSource* webkit_web_data_source_new_with_loader(PassRefPtr<WebKit::DocumentLoader> loader) |
| { |
| WebKitWebDataSource* webDataSource = WEBKIT_WEB_DATA_SOURCE(g_object_new(WEBKIT_TYPE_WEB_DATA_SOURCE, NULL)); |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| priv->loader = loader.releaseRef(); |
| |
| return webDataSource; |
| } |
| |
| /** |
| * webkit_web_data_source_new: |
| * |
| * Creates a new #WebKitWebDataSource instance. The URL of the |
| * #WebKitWebDataSource will be set to "about:blank". |
| * |
| * Return: a new #WebKitWebDataSource. |
| * |
| * Since: 1.1.14 |
| */ |
| WebKitWebDataSource* webkit_web_data_source_new() |
| { |
| WebKitNetworkRequest* request = webkit_network_request_new("about:blank"); |
| WebKitWebDataSource* datasource = webkit_web_data_source_new_with_request(request); |
| g_object_unref(request); |
| |
| return datasource; |
| } |
| |
| /** |
| * webkit_web_data_source_new_with_request: |
| * @request: the #WebKitNetworkRequest to use to create this data source |
| * |
| * Creates a new #WebKitWebDataSource from a #WebKitNetworkRequest. Normally, |
| * #WebKitWebFrame objects create their data sources so you will almost never |
| * want to invoke this method directly. |
| * |
| * Returns: a new #WebKitWebDataSource |
| * |
| * Since: 1.1.14 |
| */ |
| WebKitWebDataSource* webkit_web_data_source_new_with_request(WebKitNetworkRequest* request) |
| { |
| ASSERT(request); |
| |
| const gchar* uri = webkit_network_request_get_uri(request); |
| |
| WebKitWebDataSource* datasource; |
| datasource = webkit_web_data_source_new_with_loader( |
| WebKit::DocumentLoader::create(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), |
| SubstituteData())); |
| |
| WebKitWebDataSourcePrivate* priv = datasource->priv; |
| priv->initialRequest = request; |
| |
| return datasource; |
| } |
| |
| /** |
| * webkit_web_data_source_get_web_frame |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Returns the #WebKitWebFrame that represents this data source |
| * |
| * Return value: the #WebKitWebFrame that represents the @data_source. The |
| * #WebKitWebFrame is owned by WebKit and should not be freed or destroyed. |
| * This will return %NULL of the @data_source is not attached to a frame. |
| * |
| * Since: 1.1.14 |
| */ |
| WebKitWebFrame* webkit_web_data_source_get_web_frame(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| FrameLoader* frameLoader = priv->loader->frameLoader(); |
| |
| if (!frameLoader) |
| return NULL; |
| |
| return static_cast<WebKit::FrameLoaderClient*>(frameLoader->client())->webFrame(); |
| } |
| |
| /** |
| * webkit_web_data_source_get_initial_request: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Returns a reference to the original request that was used to load the web |
| * content. The #WebKitNetworkRequest returned by this method is the request |
| * prior to the "committed" load state. See webkit_web_data_source_get_request |
| * for getting the "committed" request. |
| * |
| * Return value: the original #WebKitNetworkRequest |
| * |
| * Since: 1.1.14 |
| */ |
| WebKitNetworkRequest* webkit_web_data_source_get_initial_request(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| ResourceRequest request = priv->loader->originalRequest(); |
| |
| if (priv->initialRequest) |
| g_object_unref(priv->initialRequest); |
| |
| priv->initialRequest = webkit_network_request_new_with_core_request(request); |
| return priv->initialRequest; |
| } |
| |
| /** |
| * webkit_web_data_source_get_request: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Returns a #WebKitNetworkRequest that was used to create this |
| * #WebKitWebDataSource. The #WebKitNetworkRequest returned by this method is |
| * the request that was "committed", and hence, different from the request you |
| * get from the webkit_web_data_source_get_initial_request method. |
| * |
| * Return value: the #WebKitNetworkRequest that created the @data_source or |
| * %NULL if the @data_source is not attached to the frame or the frame hasn't |
| * been loaded. |
| * |
| * Since: 1.1.14 |
| */ |
| WebKitNetworkRequest* webkit_web_data_source_get_request(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| FrameLoader* frameLoader = priv->loader->frameLoader(); |
| if (!frameLoader || !frameLoader->frameHasLoaded()) |
| return NULL; |
| |
| ResourceRequest request = priv->loader->request(); |
| |
| if (priv->networkRequest) |
| g_object_unref(priv->networkRequest); |
| |
| priv->networkRequest = webkit_network_request_new_with_core_request(request); |
| return priv->networkRequest; |
| } |
| |
| /** |
| * webkit_web_data_source_get_encoding: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Returns the text encoding name as set in the #WebKitWebView, or if not, the |
| * text encoding of the response. |
| * |
| * Return value: the encoding name of the #WebKitWebView or of the response. |
| * |
| * Since: 1.1.14 |
| */ |
| G_CONST_RETURN gchar* webkit_web_data_source_get_encoding(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| String textEncodingName = priv->loader->overrideEncoding(); |
| |
| if (!textEncodingName) |
| textEncodingName = priv->loader->response().textEncodingName(); |
| |
| CString encoding = textEncodingName.utf8(); |
| g_free(priv->textEncoding); |
| priv->textEncoding = g_strdup(encoding.data()); |
| return priv->textEncoding; |
| } |
| |
| /** |
| * webkit_web_data_source_is_loading: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Determines whether the data source is in the process of loading its content. |
| * |
| * Return value: %TRUE if the @data_source is still loading, %FALSE otherwise |
| * |
| * Since: 1.1.14 |
| */ |
| gboolean webkit_web_data_source_is_loading(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| |
| return priv->loader->isLoadingInAPISense(); |
| } |
| |
| /** |
| * webkit_web_data_source_get_data: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Returns the raw data that represents the the frame's content.The data will |
| * be incomplete until the data has finished loading. Returns %NULL if the web |
| * frame hasn't loaded any data. Use webkit_web_data_source_is_loading to test |
| * if data source is in the process of loading. |
| * |
| * Return value: a #GString which contains the raw data that represents the @data_source or %NULL if the |
| * @data_source hasn't loaded any data. |
| * |
| * Since: 1.1.14 |
| */ |
| GString* webkit_web_data_source_get_data(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| |
| RefPtr<SharedBuffer> mainResourceData = priv->loader->mainResourceData(); |
| |
| if (!mainResourceData) |
| return NULL; |
| |
| if (priv->data) { |
| g_string_free(priv->data, TRUE); |
| priv->data = NULL; |
| } |
| |
| priv->data = g_string_new_len(mainResourceData->data(), mainResourceData->size()); |
| return priv->data; |
| } |
| |
| /** |
| * webkit_web_data_source_get_main_resource: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Returns the main resource of the @data_source |
| * |
| * Return value: a new #WebKitWebResource representing the main resource of |
| * the @data_source. |
| * |
| * Since: 1.1.14 |
| */ |
| WebKitWebResource* webkit_web_data_source_get_main_resource(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| |
| if (priv->mainresource) |
| return priv->mainresource; |
| |
| WebKitWebFrame* webFrame = webkit_web_data_source_get_web_frame(webDataSource); |
| WebKitWebView* webView = getViewFromFrame(webFrame); |
| |
| priv->mainresource = WEBKIT_WEB_RESOURCE(g_object_ref(webkit_web_view_get_main_resource(webView))); |
| |
| return priv->mainresource; |
| } |
| |
| /** |
| * webkit_web_data_source_get_unreachable_uri: |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Return the unreachable URI of @data_source. The @data_source will have an |
| * unreachable URL if it was created using #WebKitWebFrame's |
| * webkit_web_frame_load_alternate_html_string method. |
| * |
| * Return value: the unreachable URL of @data_source or %NULL if there is no unreachable URL. |
| * |
| * Since: 1.1.14 |
| */ |
| G_CONST_RETURN gchar* webkit_web_data_source_get_unreachable_uri(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebDataSourcePrivate* priv = webDataSource->priv; |
| const KURL& unreachableURL = priv->loader->unreachableURL(); |
| |
| if (unreachableURL.isEmpty()) |
| return NULL; |
| |
| g_free(priv->unreachableURL); |
| priv->unreachableURL = g_strdup(unreachableURL.string().utf8().data()); |
| return priv->unreachableURL; |
| } |
| |
| /** |
| * webkit_web_data_source_get_subresources |
| * @data_source: a #WebKitWebDataSource |
| * |
| * Gives you a #GList of #WebKitWebResource objects that compose the |
| * #WebView to which this #WebKitWebDataSource is attached. |
| * |
| * Return value: a #GList of #WebKitResource objects; the objects are |
| * owned by WebKit, but the GList must be freed. |
| * |
| * Since: 1.1.15 |
| */ |
| GList* webkit_web_data_source_get_subresources(WebKitWebDataSource* webDataSource) |
| { |
| g_return_val_if_fail(WEBKIT_IS_WEB_DATA_SOURCE(webDataSource), NULL); |
| |
| WebKitWebFrame* webFrame = webkit_web_data_source_get_web_frame(webDataSource); |
| WebKitWebView* webView = getViewFromFrame(webFrame); |
| |
| return webkit_web_view_get_subresources(webView); |
| } |