summaryrefslogtreecommitdiff
path: root/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp')
-rw-r--r--Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp422
1 files changed, 422 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp
new file mode 100644
index 000000000..63fe2a991
--- /dev/null
+++ b/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2012 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
+ * License as published by the Free Software Foundation; either
+ * version 2,1 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 "WebKitWebPage.h"
+
+#include "ImageOptions.h"
+#include "ImmutableDictionary.h"
+#include "InjectedBundle.h"
+#include "WKBundleAPICast.h"
+#include "WKBundleFrame.h"
+#include "WebFrame.h"
+#include "WebImage.h"
+#include "WebKitDOMDocumentPrivate.h"
+#include "WebKitMarshal.h"
+#include "WebKitPrivate.h"
+#include "WebKitURIRequestPrivate.h"
+#include "WebKitURIResponsePrivate.h"
+#include "WebKitWebPagePrivate.h"
+#include "WebProcess.h"
+#include <WebCore/Document.h>
+#include <WebCore/DocumentLoader.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <glib/gi18n-lib.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+using namespace WebCore;
+
+enum {
+ DOCUMENT_LOADED,
+ SEND_REQUEST,
+
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+
+ PROP_URI
+};
+
+struct _WebKitWebPagePrivate {
+ WebPage* webPage;
+
+ CString uri;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+WEBKIT_DEFINE_TYPE(WebKitWebPage, webkit_web_page, G_TYPE_OBJECT)
+
+static CString getProvisionalURLForFrame(WebFrame* webFrame)
+{
+ DocumentLoader* documentLoader = webFrame->coreFrame()->loader()->provisionalDocumentLoader();
+ if (!documentLoader->unreachableURL().isEmpty())
+ return documentLoader->unreachableURL().string().utf8();
+
+ return documentLoader->url().string().utf8();
+}
+
+static void webkitWebPageSetURI(WebKitWebPage* webPage, const CString& uri)
+{
+ if (webPage->priv->uri == uri)
+ return;
+
+ webPage->priv->uri = uri;
+ g_object_notify(G_OBJECT(webPage), "uri");
+}
+
+static void didStartProvisionalLoadForFrame(WKBundlePageRef, WKBundleFrameRef frame, WKTypeRef*, const void *clientInfo)
+{
+ if (!WKBundleFrameIsMainFrame(frame))
+ return;
+
+ webkitWebPageSetURI(WEBKIT_WEB_PAGE(clientInfo), getProvisionalURLForFrame(toImpl(frame)));
+}
+
+static void didReceiveServerRedirectForProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo)
+{
+ if (!WKBundleFrameIsMainFrame(frame))
+ return;
+
+ webkitWebPageSetURI(WEBKIT_WEB_PAGE(clientInfo), getProvisionalURLForFrame(toImpl(frame)));
+}
+
+static void didSameDocumentNavigationForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef* userData, const void *clientInfo)
+{
+ if (!WKBundleFrameIsMainFrame(frame))
+ return;
+
+ webkitWebPageSetURI(WEBKIT_WEB_PAGE(clientInfo), toImpl(frame)->coreFrame()->document()->url().string().utf8());
+}
+
+static void didFinishDocumentLoadForFrame(WKBundlePageRef, WKBundleFrameRef frame, WKTypeRef*, const void *clientInfo)
+{
+ if (!WKBundleFrameIsMainFrame(frame))
+ return;
+
+ g_signal_emit(WEBKIT_WEB_PAGE(clientInfo), signals[DOCUMENT_LOADED], 0);
+}
+
+static void didInitiateLoadForResource(WKBundlePageRef page, WKBundleFrameRef frame, uint64_t identifier, WKURLRequestRef request, bool pageLoadIsProvisional, const void*)
+{
+ ImmutableDictionary::MapType message;
+ message.set(String::fromUTF8("Page"), toImpl(page));
+ message.set(String::fromUTF8("Frame"), toImpl(frame));
+ message.set(String::fromUTF8("Identifier"), WebUInt64::create(identifier));
+ message.set(String::fromUTF8("Request"), toImpl(request));
+ WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidInitiateLoadForResource"), ImmutableDictionary::adopt(message).get());
+}
+
+static WKURLRequestRef willSendRequestForFrame(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, WKURLRequestRef wkRequest, WKURLResponseRef wkRedirectResponse, const void* clientInfo)
+{
+ GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(wkRequest)->resourceRequest()));
+ GRefPtr<WebKitURIResponse> redirectResponse = wkRedirectResponse ? adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkRedirectResponse)->resourceResponse())) : 0;
+
+ gboolean returnValue;
+ g_signal_emit(WEBKIT_WEB_PAGE(clientInfo), signals[SEND_REQUEST], 0, request.get(), redirectResponse.get(), &returnValue);
+ if (returnValue)
+ return 0;
+
+ ResourceRequest resourceRequest;
+ webkitURIRequestGetResourceRequest(request.get(), resourceRequest);
+ RefPtr<WebURLRequest> newRequest = WebURLRequest::create(resourceRequest);
+
+ ImmutableDictionary::MapType message;
+ message.set(String::fromUTF8("Page"), toImpl(page));
+ message.set(String::fromUTF8("Identifier"), WebUInt64::create(identifier));
+ message.set(String::fromUTF8("Request"), newRequest.get());
+ if (!toImpl(wkRedirectResponse)->resourceResponse().isNull())
+ message.set(String::fromUTF8("RedirectResponse"), toImpl(wkRedirectResponse));
+ WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidSendRequestForResource"), ImmutableDictionary::adopt(message).get());
+
+ return toAPI(newRequest.release().leakRef());
+}
+
+static void didReceiveResponseForResource(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, WKURLResponseRef response, const void*)
+{
+ ImmutableDictionary::MapType message;
+ message.set(String::fromUTF8("Page"), toImpl(page));
+ message.set(String::fromUTF8("Identifier"), WebUInt64::create(identifier));
+ message.set(String::fromUTF8("Response"), toImpl(response));
+ WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidReceiveResponseForResource"), ImmutableDictionary::adopt(message).get());
+}
+
+static void didReceiveContentLengthForResource(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, uint64_t length, const void*)
+{
+ ImmutableDictionary::MapType message;
+ message.set(String::fromUTF8("Page"), toImpl(page));
+ message.set(String::fromUTF8("Identifier"), WebUInt64::create(identifier));
+ message.set(String::fromUTF8("ContentLength"), WebUInt64::create(length));
+ WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidReceiveContentLengthForResource"), ImmutableDictionary::adopt(message).get());
+}
+
+static void didFinishLoadForResource(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, const void*)
+{
+ ImmutableDictionary::MapType message;
+ message.set(String::fromUTF8("Page"), toImpl(page));
+ message.set(String::fromUTF8("Identifier"), WebUInt64::create(identifier));
+ WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidFinishLoadForResource"), ImmutableDictionary::adopt(message).get());
+}
+
+static void didFailLoadForResource(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, WKErrorRef error, const void*)
+{
+ ImmutableDictionary::MapType message;
+ message.set(String::fromUTF8("Page"), toImpl(page));
+ message.set(String::fromUTF8("Identifier"), WebUInt64::create(identifier));
+ message.set(String::fromUTF8("Error"), toImpl(error));
+ WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidFailLoadForResource"), ImmutableDictionary::adopt(message).get());
+}
+
+static void webkitWebPageGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitWebPage* webPage = WEBKIT_WEB_PAGE(object);
+
+ switch (propId) {
+ case PROP_URI:
+ g_value_set_string(value, webkit_web_page_get_uri(webPage));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ }
+}
+
+static void webkit_web_page_class_init(WebKitWebPageClass* klass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(klass);
+
+ gObjectClass->get_property = webkitWebPageGetProperty;
+
+ /**
+ * WebKitWebPage:uri:
+ *
+ * The current active URI of the #WebKitWebPage.
+ */
+ g_object_class_install_property(
+ gObjectClass,
+ PROP_URI,
+ g_param_spec_string(
+ "uri",
+ _("URI"),
+ _("The current active URI of the web page"),
+ 0,
+ WEBKIT_PARAM_READABLE));
+
+ /**
+ * WebKitWebPage::document-loaded:
+ * @web_page: the #WebKitWebPage on which the signal is emitted
+ *
+ * This signal is emitted when the DOM document of a #WebKitWebPage has been
+ * loaded.
+ *
+ * You can wait for this signal to get the DOM document with
+ * webkit_web_page_get_dom_document().
+ */
+ signals[DOCUMENT_LOADED] = g_signal_new(
+ "document-loaded",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 0);
+
+ /**
+ * WebKitWebPage::send-request:
+ * @web_page: the #WebKitWebPage on which the signal is emitted
+ * @request: a #WebKitURIRequest
+ * @redirected_response: a #WebKitURIResponse, or %NULL
+ *
+ * This signal is emitted when @request is about to be sent to
+ * the server. This signal can be used to modify the #WebKitURIRequest
+ * that will be sent to the server. You can also cancel the resource load
+ * operation by connecting to this signal and returning %TRUE.
+ *
+ * In case of a server redirection this signal is
+ * emitted again with the @request argument containing the new
+ * request to be sent to the server due to the redirection and the
+ * @redirected_response parameter containing the response
+ * received by the server for the initial request.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to continue emission of the event.
+ */
+ signals[SEND_REQUEST] = g_signal_new(
+ "send-request",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__OBJECT_OBJECT,
+ G_TYPE_BOOLEAN, 2,
+ WEBKIT_TYPE_URI_REQUEST,
+ WEBKIT_TYPE_URI_RESPONSE);
+}
+
+WebKitWebPage* webkitWebPageCreate(WebPage* webPage)
+{
+ WebKitWebPage* page = WEBKIT_WEB_PAGE(g_object_new(WEBKIT_TYPE_WEB_PAGE, NULL));
+ page->priv->webPage = webPage;
+
+ WKBundlePageLoaderClient loaderClient = {
+ kWKBundlePageResourceLoadClientCurrentVersion,
+ page,
+ didStartProvisionalLoadForFrame,
+ didReceiveServerRedirectForProvisionalLoadForFrame,
+ 0, // didFailProvisionalLoadWithErrorForFrame
+ 0, // didCommitLoadForFrame
+ didFinishDocumentLoadForFrame,
+ 0, // didFinishLoadForFrame
+ 0, // didFailLoadWithErrorForFrame
+ didSameDocumentNavigationForFrame,
+ 0, // didReceiveTitleForFrame
+ 0, // didFirstLayoutForFrame
+ 0, // didFirstVisuallyNonEmptyLayoutForFrame
+ 0, // didRemoveFrameFromHierarchy
+ 0, // didDisplayInsecureContentForFrame
+ 0, // didRunInsecureContentForFrame
+ 0, // didClearWindowObjectForFrame
+ 0, // didCancelClientRedirectForFrame
+ 0, // willPerformClientRedirectForFrame
+ 0, // didHandleOnloadEventsForFrame
+ 0, // didLayoutForFrame
+ 0, // didNewFirstVisuallyNonEmptyLayout
+ 0, // didDetectXSSForFrame
+ 0, // shouldGoToBackForwardListItem
+ 0, // globalObjectIsAvailableForFrame
+ 0, // willDisconnectDOMWindowExtensionFromGlobalObject
+ 0, // didReconnectDOMWindowExtensionToGlobalObject
+ 0, // willDestroyGlobalObjectForDOMWindowExtension
+ 0, // didFinishProgress
+ 0, // shouldForceUniversalAccessFromLocalURL
+ 0, // didReceiveIntentForFrame_unavailable
+ 0, // registerIntentServiceForFrame_unavailable
+ 0, // didLayout
+ 0, // featuresUsedInPage
+ 0, // willLoadURLRequest;
+ 0, // willLoadDataRequest;
+ };
+ WKBundlePageSetPageLoaderClient(toAPI(webPage), &loaderClient);
+
+ WKBundlePageResourceLoadClient resourceLoadClient = {
+ kWKBundlePageResourceLoadClientCurrentVersion,
+ page,
+ didInitiateLoadForResource,
+ willSendRequestForFrame,
+ didReceiveResponseForResource,
+ didReceiveContentLengthForResource,
+ didFinishLoadForResource,
+ didFailLoadForResource,
+ 0, // shouldCacheResponse
+ 0 // shouldUseCredentialStorage
+ };
+ WKBundlePageSetResourceLoadClient(toAPI(webPage), &resourceLoadClient);
+
+ return page;
+}
+
+void webkitWebPageDidReceiveMessage(WebKitWebPage* page, const String& messageName, ImmutableDictionary& message)
+{
+ if (messageName == String("GetSnapshot")) {
+ SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(static_cast<WebUInt64*>(message.get("SnapshotOptions"))->value());
+ uint64_t callbackID = static_cast<WebUInt64*>(message.get("CallbackID"))->value();
+ SnapshotRegion region = static_cast<SnapshotRegion>(static_cast<WebUInt64*>(message.get("SnapshotRegion"))->value());
+
+ RefPtr<WebImage> snapshotImage;
+ WebPage* webPage = page->priv->webPage;
+ if (WebCore::FrameView* frameView = webPage->mainFrameView()) {
+ WebCore::IntRect snapshotRect;
+ switch (region) {
+ case SnapshotRegionVisible:
+ snapshotRect = frameView->visibleContentRect(WebCore::ScrollableArea::ExcludeScrollbars);
+ break;
+ case SnapshotRegionFullDocument:
+ snapshotRect = WebCore::IntRect(WebCore::IntPoint(0, 0), frameView->contentsSize());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ if (!snapshotRect.isEmpty())
+ snapshotImage = webPage->scaledSnapshotWithOptions(snapshotRect, 1, snapshotOptions | SnapshotOptionsShareable);
+ }
+
+ ImmutableDictionary::MapType messageReply;
+ messageReply.set("Page", webPage);
+ messageReply.set("CallbackID", WebUInt64::create(callbackID));
+ messageReply.set("Snapshot", snapshotImage);
+ WebProcess::shared().injectedBundle()->postMessage("WebPage.DidGetSnapshot", ImmutableDictionary::adopt(messageReply).get());
+ } else
+ ASSERT_NOT_REACHED();
+}
+
+/**
+ * webkit_web_page_get_dom_document:
+ * @web_page: a #WebKitWebPage
+ *
+ * Get the #WebKitDOMDocument currently loaded in @web_page
+ *
+ * Returns: the #WebKitDOMDocument currently loaded, or %NULL
+ * if no document is currently loaded.
+ */
+WebKitDOMDocument* webkit_web_page_get_dom_document(WebKitWebPage* webPage)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_PAGE(webPage), 0);
+
+ Frame* coreFrame = webPage->priv->webPage->mainFrame();
+ if (!coreFrame)
+ return 0;
+
+ return kit(coreFrame->document());
+}
+
+/**
+ * webkit_web_page_get_id:
+ * @web_page: a #WebKitWebPage
+ *
+ * Get the identifier of the #WebKitWebPage
+ *
+ * Returns: the identifier of @web_page
+ */
+guint64 webkit_web_page_get_id(WebKitWebPage* webPage)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_PAGE(webPage), 0);
+
+ return webPage->priv->webPage->pageID();
+}
+
+/**
+ * webkit_web_page_get_uri:
+ * @web_page: a #WebKitWebPage
+ *
+ * Returns the current active URI of @web_page.
+ *
+ * You can monitor the active URI by connecting to the notify::uri
+ * signal of @web_page.
+ *
+ * Returns: the current active URI of @web_view or %NULL if nothing has been
+ * loaded yet.
+ */
+const gchar* webkit_web_page_get_uri(WebKitWebPage* webPage)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_PAGE(webPage), 0);
+
+ return webPage->priv->uri.data();
+}