summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/gtk
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-08-12 09:27:39 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-08-12 09:27:39 +0200
commit3749d61e1f7a59f5ec5067e560af1eb610c82015 (patch)
tree73dc228333948738bbe02976cacca8cd382bc978 /Source/WebKit2/UIProcess/API/gtk
parentb32b4dcd9a51ab8de6afc53d9e17f8707e1f7a5e (diff)
downloadqtwebkit-3749d61e1f7a59f5ec5067e560af1eb610c82015.tar.gz
Imported WebKit commit a77350243e054f3460d1137301d8b3faee3d2052 (http://svn.webkit.org/repository/webkit/trunk@125365)
New snapshot with build fixes for latest API changes in Qt and all WK1 Win MSVC fixes upstream
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk')
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp3
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp11
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettingsPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp14
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp36
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp5
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp268
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h36
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp9
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt5
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp23
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp5
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp23
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp41
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp98
22 files changed, 523 insertions, 74 deletions
diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
index 8ecd480e5..5a6adae0a 100644
--- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
@@ -142,6 +142,9 @@ void PageClientImpl::toolTipChanged(const String&, const String& newToolTip)
void PageClientImpl::setCursor(const Cursor& cursor)
{
+ if (!gtk_widget_get_realized(m_viewWidget))
+ return;
+
// [GTK] Widget::setCursor() gets called frequently
// http://bugs.webkit.org/show_bug.cgi?id=16388
// Setting the cursor may be an expensive operation in some backends,
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h
index e01909201..333e68d18 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h
@@ -28,7 +28,7 @@
#include "WebBackForwardList.h"
#include "WebKitBackForwardList.h"
-#include <WebKit2/WebKit2.h>
+#include <WebKit2/WebKit2_C.h>
WebKitBackForwardList* webkitBackForwardListCreate(WKBackForwardListRef);
WebKitBackForwardListItem* webkitBackForwardListItemGetOrCreate(WKBackForwardListItemRef);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp
index 8cd149c5b..6c3bf920a 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp
@@ -65,16 +65,7 @@ static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef us
if (!WKFrameIsMainFrame(frame))
return;
- WebKitWebView* webView = WEBKIT_WEB_VIEW(clientInfo);
- WebKitWebResource* resource = webkit_web_view_get_main_resource(webView);
- if (resource) {
- // We might not have a resource if this load is a content replacement.
- // FIXME: For some reason, when going back/forward this callback is emitted even before
- // didInitiateLoadForResource(), so we don't have a main resource at this point either.
- webkitURIResponseSetCertificateInfo(webkit_web_resource_get_response(resource), WKFrameGetCertificateInfo(frame));
- }
-
- webkitWebViewLoadChanged(webView, WEBKIT_LOAD_COMMITTED);
+ webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED);
}
static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
index 62580c83e..e02caab64 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
@@ -21,7 +21,7 @@
#define WebKitPolicyDecisionPrivate_h
#include "WebKitPolicyDecision.h"
-#include <WebKit2/WebKit2.h>
+#include <WebKit2/WebKit2_C.h>
void webkitPolicyDecisionSetListener(WebKitPolicyDecision*, WKFramePolicyListenerRef);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
index aa8a71bf9..8fede827f 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
@@ -41,7 +41,7 @@
#include <WebKit2/WKSoupRequestManager.h>
#include <WebKit2/WKString.h>
#include <WebKit2/WKTextChecker.h>
-#include <WebKit2/WebKit2.h>
+#include <WebKit2/WebKit2_C.h>
#include <glib.h>
#include <wtf/Assertions.h>
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettingsPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettingsPrivate.h
index a47ac7f74..4e5d23217 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettingsPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettingsPrivate.h
@@ -27,7 +27,7 @@
#define WebKitSettingsPrivate_h
#include "WebKitSettings.h"
-#include <WebKit2/WebKit2.h>
+#include <WebKit2/WebKit2_C.h>
void webkitSettingsAttachSettingsToPage(WebKitSettings*, WKPageRef);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp
index 5676bb6d7..5ae62c6fd 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp
@@ -140,13 +140,15 @@ void WebKitTextChecker::setSpellCheckingEnabled(bool enabled)
WKTextCheckerContinuousSpellCheckingEnabledStateChanged(enabled);
}
-void WebKitTextChecker::setSpellCheckingLanguages(const String& languages)
+const CString& WebKitTextChecker::getSpellCheckingLanguages()
{
- if (m_spellCheckingLanguages == languages)
- return;
- m_spellCheckingLanguages = languages;
+ String spellCheckingLanguages = m_textChecker->getSpellCheckingLanguages();
+ m_spellCheckingLanguages = spellCheckingLanguages.isEmpty() ? CString() : spellCheckingLanguages.utf8();
+ return m_spellCheckingLanguages;
+}
- // We need to update the languages in the enchant-based checker too.
- m_textChecker->updateSpellCheckingLanguages(languages);
+void WebKitTextChecker::setSpellCheckingLanguages(const CString& languages)
+{
+ m_textChecker->updateSpellCheckingLanguages(String::fromUTF8(languages.data()));
}
#endif // ENABLE(SPELLCHECK)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h
index dd7583a3a..3cca5622a 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h
@@ -26,6 +26,7 @@
#include <wtf/FastAllocBase.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
class WebKitTextChecker {
WTF_MAKE_FAST_ALLOCATED;
@@ -43,14 +44,14 @@ public:
void ignoreWord(const String& word);
// To be called from WebKitWebContext only.
- const String getSpellCheckingLanguages() { return m_spellCheckingLanguages; }
- void setSpellCheckingLanguages(const String& spellCheckingLanguages);
+ const CString& getSpellCheckingLanguages();
+ void setSpellCheckingLanguages(const CString& spellCheckingLanguages);
private:
WebKitTextChecker();
OwnPtr<WebCore::TextCheckerEnchant> m_textChecker;
- String m_spellCheckingLanguages;
+ CString m_spellCheckingLanguages;
bool m_spellCheckingEnabled;
};
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
index 4008e865f..fe9df9f75 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
@@ -77,7 +77,6 @@ struct _WebKitWebContextPrivate {
#endif
#if ENABLE(SPELLCHECK)
OwnPtr<WebKitTextChecker> textChecker;
- GOwnPtr<gchar> spellCheckingLanguages;
#endif
};
@@ -125,7 +124,7 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
static gpointer createDefaultWebContext(gpointer)
{
static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL)));
- webContext->priv->context = WKContextGetSharedProcessContext();
+ webContext->priv->context = WKContextCreate();
webContext->priv->requestManager = WKContextGetSoupRequestManager(webContext->priv->context.get());
WKContextSetCacheModel(webContext->priv->context.get(), kWKCacheModelPrimaryWebBrowser);
attachDownloadClientToContext(webContext.get());
@@ -432,7 +431,7 @@ void webkit_web_context_register_uri_scheme(WebKitWebContext* context, const cha
* webkit_web_context_get_spell_checking_enabled:
* @context: a #WebKitWebContext
*
- * Get the current status of the spell checking feature.
+ * Get whether spell checking feature is currently enabled.
*
* Returns: %TRUE If spell checking is enabled, or %FALSE otherwise.
*/
@@ -468,18 +467,24 @@ void webkit_web_context_set_spell_checking_enabled(WebKitWebContext* context, gb
* @context: a #WebKitWebContext
*
* Get the the list of spell checking languages associated with
- * @context, separated by commas. See
- * webkit_web_context_set_spell_checking_languages() for more details
- * on the format of the languages in the list.
+ * @context separated by commas, or %NULL if no languages have been
+ * previously set.
+
+ * See webkit_web_context_set_spell_checking_languages() for more
+ * details on the format of the languages in the list.
*
- * Returns: (transfer none): A comma separated list of languages.
+ * Returns: (transfer none): A comma separated list of languages if
+ * available, or %NULL otherwise.
*/
const gchar* webkit_web_context_get_spell_checking_languages(WebKitWebContext* context)
{
g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0);
#if ENABLE(SPELLCHECK)
- return context->priv->spellCheckingLanguages.get();
+ CString spellCheckingLanguages = context->priv->textChecker->getSpellCheckingLanguages();
+ if (spellCheckingLanguages.isNull())
+ return 0;
+ return spellCheckingLanguages.data();
#else
return 0;
#endif
@@ -488,25 +493,28 @@ const gchar* webkit_web_context_get_spell_checking_languages(WebKitWebContext* c
/**
* webkit_web_context_set_spell_checking_languages:
* @context: a #WebKitWebContext
- * @languages: (allow-none): new list of spell checking
- * languages separated by commas, or %NULL
+ * @languages: new list of spell checking languages separated by
+ * commas
*
* Set the list of spell checking languages to be used for spell
- * checking, separated by commas. In case %NULL is passed, the default
- * value as returned by gtk_get_default_language() will be used.
+ * checking, separated by commas.
*
* The locale string typically is in the form lang_COUNTRY, where lang
* is an ISO-639 language code, and COUNTRY is an ISO-3166 country code.
* For instance, sv_FI for Swedish as written in Finland or pt_BR
* for Portuguese as written in Brazil.
+ *
+ * You need to call this function with a valid list of languages at
+ * least once in order to properly enable the spell checking feature
+ * in WebKit.
*/
void webkit_web_context_set_spell_checking_languages(WebKitWebContext* context, const gchar* languages)
{
g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
+ g_return_if_fail(languages);
#if ENABLE(SPELLCHECK)
- context->priv->textChecker->setSpellCheckingLanguages(String(languages));
- context->priv->spellCheckingLanguages.set(g_strdup(languages));
+ context->priv->textChecker->setSpellCheckingLanguages(languages);
#endif
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
index 7fbe28a0a..5ca5e989d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
@@ -243,6 +243,11 @@ void webkitWebResourceFailed(WebKitWebResource* resource, GError* error)
g_signal_emit(resource, signals[FINISHED], 0, NULL);
}
+WKFrameRef webkitWebResourceGetFrame(WebKitWebResource* resource)
+{
+ return resource->priv->wkFrame.get();
+}
+
/**
* webkit_web_resource_get_uri:
* @resource: a #WebKitWebResource
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
index 5011ae4dd..ed1fe02f1 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
@@ -29,6 +29,7 @@ void webkitWebResourceSetResponse(WebKitWebResource*, WebKitURIResponse*);
void webkitWebResourceNotifyProgress(WebKitWebResource*, guint64 bytesReceived);
void webkitWebResourceFinished(WebKitWebResource*);
void webkitWebResourceFailed(WebKitWebResource*, GError*);
+WKFrameRef webkitWebResourceGetFrame(WebKitWebResource*);
#endif // WebKitWebResourcePrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
index 8bf4d8fe0..80e5fff23 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
@@ -124,6 +124,10 @@ struct _WebKitWebViewPrivate {
CString activeURI;
ReplaceContentStatus replaceContentStatus;
+ bool waitingForMainResource;
+ gulong mainResourceResponseHandlerID;
+ WebKitLoadEvent lastDelayedEvent;
+
GRefPtr<WebKitBackForwardList> backForwardList;
GRefPtr<WebKitSettings> settings;
GRefPtr<WebKitWindowProperties> windowProperties;
@@ -268,6 +272,14 @@ static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView
}
+static void webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(WebKitWebView* webView)
+{
+ WebKitWebViewPrivate* priv = webView->priv;
+ if (priv->mainResourceResponseHandlerID)
+ g_signal_handler_disconnect(priv->mainResource.get(), priv->mainResourceResponseHandlerID);
+ priv->mainResourceResponseHandlerID = 0;
+}
+
static void fileChooserDialogResponseCallback(GtkDialog* dialog, gint responseID, WebKitFileChooserRequest* request)
{
GRefPtr<WebKitFileChooserRequest> adoptedRequest = adoptGRef(request);
@@ -382,7 +394,8 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu
static void webkitWebViewFinalize(GObject* object)
{
- WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(object)->priv;
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
+ WebKitWebViewPrivate* priv = webView->priv;
if (priv->javascriptGlobalContext)
JSGlobalContextRelease(priv->javascriptGlobalContext);
@@ -391,7 +404,8 @@ static void webkitWebViewFinalize(GObject* object)
if (priv->modalLoop && g_main_loop_is_running(priv->modalLoop.get()))
g_main_loop_quit(priv->modalLoop.get());
- webkitWebViewDisconnectSettingsSignalHandlers(WEBKIT_WEB_VIEW(object));
+ webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
+ webkitWebViewDisconnectSettingsSignalHandlers(webView);
priv->~WebKitWebViewPrivate();
G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
@@ -1112,20 +1126,68 @@ static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent l
return false;
}
+static void setCertificateToMainResource(WebKitWebView* webView)
+{
+ WebKitWebViewPrivate* priv = webView->priv;
+ ASSERT(priv->mainResource.get());
+
+ webkitURIResponseSetCertificateInfo(webkit_web_resource_get_response(priv->mainResource.get()),
+ WKFrameGetCertificateInfo(webkitWebResourceGetFrame(priv->mainResource.get())));
+}
+
+static void webkitWebViewEmitLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
+{
+ if (loadEvent == WEBKIT_LOAD_FINISHED) {
+ webView->priv->waitingForMainResource = false;
+ webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
+ } else
+ webkitWebViewUpdateURI(webView);
+ g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent);
+}
+
+static void webkitWebViewEmitDelayedLoadEvents(WebKitWebView* webView)
+{
+ WebKitWebViewPrivate* priv = webView->priv;
+ if (!priv->waitingForMainResource)
+ return;
+ ASSERT(priv->lastDelayedEvent == WEBKIT_LOAD_COMMITTED || priv->lastDelayedEvent == WEBKIT_LOAD_FINISHED);
+
+ if (priv->lastDelayedEvent == WEBKIT_LOAD_FINISHED)
+ webkitWebViewEmitLoadChanged(webView, WEBKIT_LOAD_COMMITTED);
+ webkitWebViewEmitLoadChanged(webView, priv->lastDelayedEvent);
+ priv->waitingForMainResource = false;
+}
+
void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
{
if (loadEvent == WEBKIT_LOAD_STARTED) {
+ // Finish a possible previous load waiting for main resource.
+ webkitWebViewEmitDelayedLoadEvents(webView);
+
webView->priv->loadingResourcesMap.clear();
webView->priv->mainResource = 0;
- } else if (loadEvent == WEBKIT_LOAD_COMMITTED)
+ webView->priv->waitingForMainResource = false;
+ } else if (loadEvent == WEBKIT_LOAD_COMMITTED) {
webView->priv->subresourcesMap.clear();
+ if (webView->priv->replaceContentStatus != ReplacingContent) {
+ if (!webView->priv->mainResource) {
+ // When a page is loaded from the history cache, the main resource load callbacks
+ // are called when the main frame load is finished. We want to make sure there's a
+ // main resource available when load has been committed, so we delay the emission of
+ // load-changed signal until main resource object has been created.
+ webView->priv->waitingForMainResource = true;
+ } else
+ setCertificateToMainResource(webView);
+ }
+ }
if (updateReplaceContentStatus(webView, loadEvent))
return;
- if (loadEvent != WEBKIT_LOAD_FINISHED)
- webkitWebViewUpdateURI(webView);
- g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent);
+ if (webView->priv->waitingForMainResource)
+ webView->priv->lastDelayedEvent = loadEvent;
+ else
+ webkitWebViewEmitLoadChanged(webView, loadEvent);
}
void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error)
@@ -1197,9 +1259,9 @@ void webkitWebViewRunAsModal(WebKitWebView* webView)
g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL);
webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE));
- GDK_THREADS_ENTER();
+ gdk_threads_leave();
g_main_loop_run(webView->priv->modalLoop.get());
- GDK_THREADS_LEAVE();
+ gdk_threads_enter();
}
void webkitWebViewClosePage(WebKitWebView* webView)
@@ -1269,6 +1331,24 @@ void webkitWebViewPrintFrame(WebKitWebView* webView, WKFrameRef wkFrame)
g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
}
+static void mainResourceResponseChangedCallback(WebKitWebResource*, GParamSpec*, WebKitWebView* webView)
+{
+ webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
+ setCertificateToMainResource(webView);
+ webkitWebViewEmitDelayedLoadEvents(webView);
+}
+
+static void waitForMainResourceResponseIfWaitingForResource(WebKitWebView* webView)
+{
+ WebKitWebViewPrivate* priv = webView->priv;
+ if (!priv->waitingForMainResource)
+ return;
+
+ webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
+ priv->mainResourceResponseHandlerID =
+ g_signal_connect(priv->mainResource.get(), "notify::response", G_CALLBACK(mainResourceResponseChangedCallback), webView);
+}
+
static inline bool webkitWebViewIsReplacingContentOrDidReplaceContent(WebKitWebView* webView)
{
return (webView->priv->replaceContentStatus == ReplacingContent || webView->priv->replaceContentStatus == DidReplaceContent);
@@ -1281,8 +1361,10 @@ void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WKFrameRef wkFrame
WebKitWebViewPrivate* priv = webView->priv;
WebKitWebResource* resource = webkitWebResourceCreate(wkFrame, request, isMainResource);
- if (WKFrameIsMainFrame(wkFrame) && (isMainResource || !priv->mainResource))
+ if (WKFrameIsMainFrame(wkFrame) && (isMainResource || !priv->mainResource)) {
priv->mainResource = resource;
+ waitForMainResourceResponseIfWaitingForResource(webView);
+ }
priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource));
g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request);
}
@@ -2318,3 +2400,171 @@ gboolean webkit_web_view_can_show_mime_type(WebKitWebView* webView, const char*
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
return page->canShowMIMEType(String::fromUTF8(mimeType));
}
+
+struct ViewSaveAsyncData {
+ WKRetainPtr<WKDataRef> wkData;
+ GRefPtr<GFile> file;
+ GRefPtr<GCancellable> cancellable;
+};
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(ViewSaveAsyncData)
+
+static void fileReplaceContentsCallback(GObject* object, GAsyncResult* result, gpointer data)
+{
+ GFile* file = G_FILE(object);
+ GRefPtr<GSimpleAsyncResult> savedToFileResult = adoptGRef(G_SIMPLE_ASYNC_RESULT(data));
+
+ GError* error = 0;
+ if (!g_file_replace_contents_finish(file, result, 0, &error))
+ g_simple_async_result_take_error(savedToFileResult.get(), error);
+
+ g_simple_async_result_complete(savedToFileResult.get());
+}
+
+static void getContentsAsMHTMLDataCallback(WKDataRef wkData, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_simple_async_result_get_op_res_gpointer(result.get()));
+ GError* error = 0;
+
+ if (g_cancellable_set_error_if_cancelled(data->cancellable.get(), &error))
+ g_simple_async_result_take_error(result.get(), error);
+ else {
+ // We need to retain the data until the asyncronous process
+ // initiated by the user has finished completely.
+ data->wkData = wkData;
+
+ // If we are saving to a file we need to write the data on disk before finishing.
+ if (g_simple_async_result_get_source_tag(result.get()) == webkit_web_view_save_to_file) {
+ ASSERT(G_IS_FILE(data->file.get()));
+ g_file_replace_contents_async(data->file.get(), reinterpret_cast<const gchar*>(WKDataGetBytes(data->wkData.get())), WKDataGetSize(data->wkData.get()), 0, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
+ data->cancellable.get(), fileReplaceContentsCallback, g_object_ref(result.get()));
+ return;
+ }
+ }
+
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_web_view_save:
+ * @web_view: a #WebKitWebView
+ * @save_mode: the #WebKitSaveMode specifying how the web page should be saved.
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously save the current web page associated to the
+ * #WebKitWebView into a self-contained format using the mode
+ * specified in @save_mode.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call webkit_web_view_save_finish() to get the result of the
+ * operation.
+ */
+void webkit_web_view_save(WebKitWebView* webView, WebKitSaveMode saveMode, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+
+ // We only support MHTML at the moment.
+ g_return_if_fail(saveMode == WEBKIT_SAVE_MODE_MHTML);
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_view_save));
+ ViewSaveAsyncData* data = createViewSaveAsyncData();
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData));
+
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKPageGetContentsAsMHTMLData(wkPage, false, result, getContentsAsMHTMLDataCallback);
+}
+
+/**
+ * webkit_web_view_save_finish:
+ * @web_view: a #WebKitWebView
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_view_save().
+ *
+ * Returns: (transfer full): a #GInputStream with the result of saving
+ * the current web page or %NULL in case of error.
+ */
+GInputStream* webkit_web_view_save_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simple = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simple) == webkit_web_view_save);
+
+ if (g_simple_async_result_propagate_error(simple, error))
+ return 0;
+
+ GInputStream* dataStream = g_memory_input_stream_new();
+ ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_simple_async_result_get_op_res_gpointer(simple));
+ gsize length = WKDataGetSize(data->wkData.get());
+ if (length)
+ g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(dataStream), g_memdup(WKDataGetBytes(data->wkData.get()), length), length, g_free);
+
+ return dataStream;
+}
+
+/**
+ * webkit_web_view_save_to_file:
+ * @web_view: a #WebKitWebView
+ * @file: the #GFile where the current web page should be saved to.
+ * @save_mode: the #WebKitSaveMode specifying how the web page should be saved.
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously save the current web page associated to the
+ * #WebKitWebView into a self-contained format using the mode
+ * specified in @save_mode and writing it to @file.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call webkit_web_view_save_to_file_finish() to get the result of the
+ * operation.
+ */
+void webkit_web_view_save_to_file(WebKitWebView* webView, GFile* file, WebKitSaveMode saveMode, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+ g_return_if_fail(G_IS_FILE(file));
+
+ // We only support MHTML at the moment.
+ g_return_if_fail(saveMode == WEBKIT_SAVE_MODE_MHTML);
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_view_save_to_file));
+ ViewSaveAsyncData* data = createViewSaveAsyncData();
+ data->file = file;
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData));
+
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKPageGetContentsAsMHTMLData(wkPage, false, result, getContentsAsMHTMLDataCallback);
+}
+
+/**
+ * webkit_web_view_save_to_file_finish:
+ * @web_view: a #WebKitWebView
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_view_save_to_file().
+ *
+ * Returns: %TRUE if the web page was successfully saved to a file or %FALSE otherwise.
+ */
+gboolean webkit_web_view_save_to_file_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), FALSE);
+
+ GSimpleAsyncResult* simple = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simple) == webkit_web_view_save_to_file);
+
+ if (g_simple_async_result_propagate_error(simple, error))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
index 2553b1840..6ebd17f04 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
@@ -118,6 +118,17 @@ typedef enum {
WEBKIT_LOAD_FINISHED
} WebKitLoadEvent;
+/**
+ * WebKitSaveMode:
+ * @WEBKIT_SAVE_MODE_MHTML: Save the current page using the MHTML format.
+ *
+ * Enum values to specify the different ways in which a #WebKitWebView
+ * can save its current web page into a self-contained file.
+ */
+typedef enum {
+ WEBKIT_SAVE_MODE_MHTML
+} WebKitSaveMode;
+
struct _WebKitWebView {
WebKitWebViewBase parent;
@@ -319,6 +330,31 @@ WEBKIT_API gboolean
webkit_web_view_can_show_mime_type (WebKitWebView *web_view,
const gchar *mime_type);
+WEBKIT_API void
+webkit_web_view_save (WebKitWebView *web_view,
+ WebKitSaveMode save_mode,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API GInputStream *
+webkit_web_view_save_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_web_view_save_to_file (WebKitWebView *web_view,
+ GFile *file,
+ WebKitSaveMode save_mode,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gboolean
+webkit_web_view_save_to_file_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
index f65fa97ed..4925b5a7c 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -101,9 +101,6 @@ struct _WebKitWebViewBasePrivate {
G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
-// Keep this in sync with the value minimumAttachedHeight in WebInspectorProxy.
-static const unsigned gMinimumAttachedInspectorHeight = 250;
-
static void webkitWebViewBaseNotifyResizerSizeForWindow(WebKitWebViewBase* webViewBase, GtkWindow* window)
{
gboolean resizerVisible;
@@ -190,7 +187,6 @@ static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* wi
&& WebInspectorProxy::isInspectorPage(WEBKIT_WEB_VIEW_BASE(widget)->priv->pageProxy.get())) {
ASSERT(!priv->inspectorView);
priv->inspectorView = widget;
- priv->inspectorViewHeight = gMinimumAttachedInspectorHeight;
} else {
GtkAllocation childAllocation;
gtk_widget_get_allocation(widget, &childAllocation);
@@ -773,12 +769,11 @@ void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase* webkitWebVie
void webkitWebViewBaseSetInspectorViewHeight(WebKitWebViewBase* webkitWebViewBase, unsigned height)
{
- if (!webkitWebViewBase->priv->inspectorView)
- return;
if (webkitWebViewBase->priv->inspectorViewHeight == height)
return;
webkitWebViewBase->priv->inspectorViewHeight = height;
- gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
+ if (webkitWebViewBase->priv->inspectorView)
+ gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
}
void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase, WebContextMenuProxyGtk* contextMenuProxy)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
index 1833fb111..f2986d1f9 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
@@ -28,7 +28,7 @@
#define WebKitWebViewPrivate_h
#include "WebKitWebView.h"
-#include <WebKit2/WebKit2.h>
+#include <WebKit2/WebKit2_C.h>
#include <wtf/text/CString.h>
void webkitWebViewLoadChanged(WebKitWebView*, WebKitLoadEvent);
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
index 73f09d5d3..92da1ebe5 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
@@ -62,6 +62,7 @@ webkit_web_context_get_type
WebKitWebView
WebKitLoadEvent
WebKitPolicyDecisionType
+WebKitSaveMode
<SUBSECTION Editing Commands>
WEBKIT_EDITING_COMMAND_CUT
@@ -105,6 +106,10 @@ webkit_web_view_get_javascript_global_context
webkit_web_view_run_javascript
webkit_web_view_run_javascript_finish
webkit_web_view_can_show_mime_type
+webkit_web_view_save
+webkit_web_view_save_finish
+webkit_web_view_save_to_file
+webkit_web_view_save_to_file_finish
<SUBSECTION WebKitJavascriptResult>
WebKitJavascriptResult
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp
index a35c8745b..d370de938 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp
@@ -35,10 +35,17 @@ static void loadChangedCallback(WebKitWebView* webView, WebKitLoadEvent loadEven
g_assert_cmpstr(test->m_redirectURI.data(), ==, test->m_activeURI.data());
test->provisionalLoadReceivedServerRedirect();
break;
- case WEBKIT_LOAD_COMMITTED:
+ case WEBKIT_LOAD_COMMITTED: {
g_assert_cmpstr(test->m_activeURI.data(), ==, webkit_web_view_get_uri(webView));
+
+ // Check that on committed we always have a main resource with a response.
+ WebKitWebResource* resource = webkit_web_view_get_main_resource(webView);
+ g_assert(resource);
+ g_assert(webkit_web_resource_get_response(resource));
+
test->loadCommitted();
break;
+ }
case WEBKIT_LOAD_FINISHED:
if (!test->m_loadFailed)
g_assert_cmpstr(test->m_activeURI.data(), ==, webkit_web_view_get_uri(webView));
@@ -170,3 +177,17 @@ void LoadTrackingTest::reload()
m_estimatedProgress = 0;
webkit_web_view_reload(m_webView);
}
+
+void LoadTrackingTest::goBack()
+{
+ m_loadEvents.clear();
+ m_estimatedProgress = 0;
+ WebViewTest::goBack();
+}
+
+void LoadTrackingTest::goForward()
+{
+ m_loadEvents.clear();
+ m_estimatedProgress = 0;
+ WebViewTest::goForward();
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h b/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h
index 2d95c48f4..562f7f038 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h
@@ -44,6 +44,8 @@ public:
void loadPlainText(const char* plainText);
void loadRequest(WebKitURIRequest*);
void reload();
+ void goBack();
+ void goForward();
void setRedirectURI(const char* uri) { m_redirectURI = uri; }
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp
index 9b023f3ed..673749411 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp
@@ -22,8 +22,6 @@
#include "WebViewTest.h"
#include <wtf/gobject/GRefPtr.h>
-static const unsigned gMinimumAttachedInspectorHeight = 250;
-
class InspectorTest: public WebViewTest {
public:
MAKE_GLIB_TEST_FIXTURE(InspectorTest);
@@ -181,6 +179,7 @@ static void testInspectorDefault(InspectorTest* test, gconstpointer)
test->resizeViewAndAttach();
g_assert(webkit_web_inspector_is_attached(test->m_inspector));
+ g_assert_cmpuint(webkit_web_inspector_get_attached_height(test->m_inspector), >=, InspectorTest::gMinimumAttachedInspectorHeight);
events = test->m_events;
g_assert_cmpint(events.size(), ==, 1);
g_assert_cmpint(events[0], ==, InspectorTest::Attach);
@@ -258,6 +257,7 @@ public:
gtk_widget_show_all(pane);
} else
pane = gtk_bin_get_child(GTK_BIN(m_parentWindow));
+ gtk_paned_set_position(GTK_PANED(pane), webkit_web_inspector_get_attached_height(m_inspector));
gtk_paned_add2(GTK_PANED(pane), GTK_WIDGET(inspectorView.get()));
return InspectorTest::attach();
@@ -301,6 +301,7 @@ static void testInspectorManualAttachDetach(CustomInspectorTest* test, gconstpoi
test->resizeViewAndAttach();
g_assert(webkit_web_inspector_is_attached(test->m_inspector));
+ g_assert_cmpuint(webkit_web_inspector_get_attached_height(test->m_inspector), >=, InspectorTest::gMinimumAttachedInspectorHeight);
events = test->m_events;
g_assert_cmpint(events.size(), ==, 1);
g_assert_cmpint(events[0], ==, InspectorTest::Attach);
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp
index 3afa2b96f..59eed7658 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp
@@ -144,6 +144,26 @@ static void testLoadProgress(LoadTrackingTest* test, gconstpointer)
g_assert_cmpfloat(test->m_estimatedProgress, ==, 1);
}
+static void testWebViewHistoryLoad(LoadTrackingTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/normal").data());
+ test->waitUntilLoadFinished();
+ assertNormalLoadHappened(test->m_loadEvents);
+
+ test->loadURI(kServer->getURIForPath("/normal2").data());
+ test->waitUntilLoadFinished();
+ assertNormalLoadHappened(test->m_loadEvents);
+
+ // Check that load process is the same for pages loaded from history cache.
+ test->goBack();
+ test->waitUntilLoadFinished();
+ assertNormalLoadHappened(test->m_loadEvents);
+
+ test->goForward();
+ test->waitUntilLoadFinished();
+ assertNormalLoadHappened(test->m_loadEvents);
+}
+
class ViewURITrackingTest: public LoadTrackingTest {
public:
MAKE_GLIB_TEST_FIXTURE(ViewURITrackingTest);
@@ -217,7 +237,7 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char*
soup_message_set_status(message, SOUP_STATUS_OK);
- if (g_str_equal(path, "/normal"))
+ if (g_str_has_prefix(path, "/normal"))
soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString));
else if (g_str_equal(path, "/error"))
soup_message_set_status(message, SOUP_STATUS_CANT_CONNECT);
@@ -248,6 +268,7 @@ void beforeAll()
LoadTrackingTest::add("WebKitWebView", "title", testWebViewTitle);
LoadTrackingTest::add("WebKitWebView", "progress", testLoadProgress);
LoadTrackingTest::add("WebKitWebView", "reload", testWebViewReload);
+ LoadTrackingTest::add("WebKitWebView", "history-load", testWebViewHistoryLoad);
// This test checks that web view notify::uri signal is correctly emitted
// and the uri is already updated when loader client signals are emitted.
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp
index f42feafb7..1b172dfee 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp
@@ -233,28 +233,37 @@ static void testWebContextURIScheme(URISchemeTest* test, gconstpointer)
static void testWebContextSpellChecker(Test* test, gconstpointer)
{
- GRefPtr<WebKitWebContext> webContext(webkit_web_context_get_default());
+ WebKitWebContext* webContext = webkit_web_context_get_default();
- // Set the language to a specific one, an empty one and a list of them.
- webkit_web_context_set_spell_checking_languages(webContext.get(), "en_US");
- const gchar* currentLanguage(webkit_web_context_get_spell_checking_languages(webContext.get()));
+ // Check what happens if no spell checking language has been set.
+ const gchar* currentLanguage = webkit_web_context_get_spell_checking_languages(webContext);
+ g_assert(!currentLanguage);
+
+ // Set the language to a specific one.
+ webkit_web_context_set_spell_checking_languages(webContext, "en_US");
+ currentLanguage = webkit_web_context_get_spell_checking_languages(webContext);
g_assert_cmpstr(currentLanguage, ==, "en_US");
- webkit_web_context_set_spell_checking_languages(webContext.get(), 0);
- currentLanguage = webkit_web_context_get_spell_checking_languages(webContext.get());
- g_assert_cmpstr(currentLanguage, ==, 0);
+ // Set the language string to list of valid languages.
+ webkit_web_context_set_spell_checking_languages(webContext, "en_GB,en_US");
+ currentLanguage = webkit_web_context_get_spell_checking_languages(webContext);
+ g_assert_cmpstr(currentLanguage, ==, "en_GB,en_US");
+
+ // Try passing a wrong language along with good ones.
+ webkit_web_context_set_spell_checking_languages(webContext, "bd_WR,en_US,en_GB");
+ currentLanguage = webkit_web_context_get_spell_checking_languages(webContext);
+ g_assert_cmpstr(currentLanguage, ==, "en_US,en_GB");
- webkit_web_context_set_spell_checking_languages(webContext.get(), "es_ES,en_US");
- currentLanguage = webkit_web_context_get_spell_checking_languages(webContext.get());
- g_assert_cmpstr(currentLanguage, ==, "es_ES,en_US");
+ // Try passing a list with only wrong languages.
+ webkit_web_context_set_spell_checking_languages(webContext, "bd_WR,wr_BD");
+ currentLanguage = webkit_web_context_get_spell_checking_languages(webContext);
+ g_assert(!currentLanguage);
// Check disabling and re-enabling spell checking.
- webkit_web_context_set_spell_checking_enabled(webContext.get(), FALSE);
- gboolean isSpellCheckingEnabled = webkit_web_context_get_spell_checking_enabled(webContext.get());
- g_assert(!isSpellCheckingEnabled);
- webkit_web_context_set_spell_checking_enabled(webContext.get(), TRUE);
- isSpellCheckingEnabled = webkit_web_context_get_spell_checking_enabled(webContext.get());
- g_assert(isSpellCheckingEnabled);
+ webkit_web_context_set_spell_checking_enabled(webContext, FALSE);
+ g_assert(!webkit_web_context_get_spell_checking_enabled(webContext));
+ webkit_web_context_set_spell_checking_enabled(webContext, TRUE);
+ g_assert(webkit_web_context_get_spell_checking_enabled(webContext));
}
void beforeAll()
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
index eec6fc786..22796bf73 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
@@ -21,6 +21,7 @@
#include "WebViewTest.h"
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
+#include <glib/gstdio.h>
#include <wtf/HashSet.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/StringHash.h>
@@ -946,6 +947,102 @@ static void testWebViewSubmitForm(FormClientTest* test, gconstpointer)
g_assert_cmpstr(static_cast<char*>(g_hash_table_lookup(values, "password")), ==, "secret");
}
+class SaveWebViewTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(SaveWebViewTest);
+
+ SaveWebViewTest()
+ : m_tempDirectory(g_dir_make_tmp("WebKit2SaveViewTest-XXXXXX", 0))
+ {
+ }
+
+ ~SaveWebViewTest()
+ {
+ if (G_IS_FILE(m_file.get()))
+ g_file_delete(m_file.get(), 0, 0);
+
+ if (G_IS_INPUT_STREAM(m_inputStream.get()))
+ g_input_stream_close(m_inputStream.get(), 0, 0);
+
+ if (m_tempDirectory)
+ g_rmdir(m_tempDirectory.get());
+ }
+
+ static void webViewSavedToStreamCallback(GObject* object, GAsyncResult* result, SaveWebViewTest* test)
+ {
+ GOwnPtr<GError> error;
+ test->m_inputStream = adoptGRef(webkit_web_view_save_finish(test->m_webView, result, &error.outPtr()));
+ g_assert(G_IS_INPUT_STREAM(test->m_inputStream.get()));
+ g_assert(!error);
+
+ test->quitMainLoop();
+ }
+
+ static void webViewSavedToFileCallback(GObject* object, GAsyncResult* result, SaveWebViewTest* test)
+ {
+ GOwnPtr<GError> error;
+ g_assert(webkit_web_view_save_to_file_finish(test->m_webView, result, &error.outPtr()));
+ g_assert(!error);
+
+ test->quitMainLoop();
+ }
+
+ void saveAndWaitForStream()
+ {
+ webkit_web_view_save(m_webView, WEBKIT_SAVE_MODE_MHTML, 0, reinterpret_cast<GAsyncReadyCallback>(webViewSavedToStreamCallback), this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ void saveAndWaitForFile()
+ {
+ m_saveDestinationFilePath.set(g_build_filename(m_tempDirectory.get(), "testWebViewSaveResult.mht", NULL));
+ m_file = adoptGRef(g_file_new_for_path(m_saveDestinationFilePath.get()));
+ webkit_web_view_save_to_file(m_webView, m_file.get(), WEBKIT_SAVE_MODE_MHTML, 0, reinterpret_cast<GAsyncReadyCallback>(webViewSavedToFileCallback), this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ GOwnPtr<char> m_tempDirectory;
+ GOwnPtr<char> m_saveDestinationFilePath;
+ GRefPtr<GInputStream> m_inputStream;
+ GRefPtr<GFile> m_file;
+};
+
+static void testWebViewSave(SaveWebViewTest* test, gconstpointer)
+{
+ test->loadHtml("<html>"
+ "<body>"
+ " <p>A paragraph with plain text</p>"
+ " <p>"
+ " A red box: <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYWDTMVwnSZnwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFklEQVQI12P8z8DAwMDAxMDAwMDAAAANHQEDK+mmyAAAAABJRU5ErkJggg=='></br>"
+ " A blue box: <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYWDTMvBHhALQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFklEQVQI12Nk4PnPwMDAxMDAwMDAAAALrwEPPIs1pgAAAABJRU5ErkJggg=='>"
+ " </p>"
+ "</body>"
+ "</html>", 0);
+ test->waitUntilLoadFinished();
+
+ // Write to a file and to an input stream.
+ test->saveAndWaitForFile();
+ test->saveAndWaitForStream();
+
+ // We should have exactly the same amount of bytes in the file
+ // than those coming from the GInputStream. We don't compare the
+ // strings read since the 'Date' field and the boundaries will be
+ // different on each case. MHTML functionality will be tested by
+ // Layout tests, so checking the amount of bytes is enough.
+ GOwnPtr<GError> error;
+ gchar buffer[512] = { 0 };
+ gssize readBytes = 0;
+ gssize totalBytesFromStream = 0;
+ while (readBytes = g_input_stream_read(test->m_inputStream.get(), &buffer, 512, 0, &error.outPtr())) {
+ g_assert(!error);
+ totalBytesFromStream += readBytes;
+ }
+
+ // Check that the file exists and that it contains the same amount of bytes.
+ GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(test->m_file.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0));
+ g_assert_cmpint(g_file_info_get_size(fileInfo.get()), ==, totalBytesFromStream);
+}
+
void beforeAll()
{
WebViewTest::add("WebKitWebView", "default-context", testWebViewDefaultContext);
@@ -965,6 +1062,7 @@ void beforeAll()
FullScreenClientTest::add("WebKitWebView", "fullscreen", testWebViewFullScreen);
WebViewTest::add("WebKitWebView", "can-show-mime-type", testWebViewCanShowMIMEType);
FormClientTest::add("WebKitWebView", "submit-form", testWebViewSubmitForm);
+ SaveWebViewTest::add("WebKitWebView", "save", testWebViewSave);
}
void afterAll()