Diff
Modified: trunk/Source/WebKit2/ChangeLog (124455 => 124456)
--- trunk/Source/WebKit2/ChangeLog 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/ChangeLog 2012-08-02 15:01:14 UTC (rev 124456)
@@ -1,3 +1,60 @@
+2012-08-02 Carlos Garcia Campos <[email protected]>
+
+ [GTK] No main resource in WebView on load committed when page has been loaded from history cache
+ https://bugs.webkit.org/show_bug.cgi?id=91482
+
+ Reviewed by Martin Robinson.
+
+ We assume that on load committed, we already have a main resource
+ in the web view, and it has already received a response. This is
+ not true for pages loaded from the history cache, so when going
+ back/forward, we don't have a main resource when the
+ load-committed signal is emitted. We must ensure that the loading
+ process documented in the API is the same for pages loaded from
+ the history cache too.
+
+ * UIProcess/API/gtk/WebKitLoaderClient.cpp:
+ (didCommitLoadForFrame): Call webkitWebViewLoadChanged() and let
+ the web view handle the certificate.
+ * UIProcess/API/gtk/WebKitWebResource.cpp:
+ (webkitWebResourceGetFrame): Helper private function to easily get
+ the WKFrame associated with a WebResource.
+ * UIProcess/API/gtk/WebKitWebResourcePrivate.h:
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (webkitWebViewDisconnectMainResourceResponseChangedSignalHandler):
+ Disconnect the notify::response signal of the main resource.
+ (webkitWebViewFinalize): Call
+ webkitWebViewDisconnectMainResourceResponseChangedSignalHandler().
+ (setCertificateToMainResource): Set the TLS certificate on the
+ response of the main resource.
+ (webkitWebViewEmitLoadChanged): Helper function to emit
+ load-chancged signal.
+ (webkitWebViewEmitDelayedLoadEvents): If we were waiting for the
+ main resource, emit the signals that were delayed.
+ (webkitWebViewLoadChanged): Do not emit committed or finished if
+ we are still waiting for the main resource. Set the TLS
+ certificate if we already have a main resource or wait until we
+ have the main resource with a response.
+ (mainResourceResponseChangedCallback): Emitted when the main
+ resource received the response. Set the certificate on the
+ response and emit load signals delayed.
+ (waitForMainResourceResponseIfWaitingForResource): If we are
+ waiting for the main resource, connect to the notify::response
+ signal of the WebResource to make sure it has a response already
+ when load signal delayed are emitted.
+ (webkitWebViewResourceLoadStarted): Call
+ waitForMainResourceResponseIfWaitingForResource().
+ * UIProcess/API/gtk/tests/LoadTrackingTest.cpp:
+ (loadChangedCallback):
+ (LoadTrackingTest::goBack):
+ (LoadTrackingTest::goForward):
+ * UIProcess/API/gtk/tests/LoadTrackingTest.h:
+ (LoadTrackingTest):
+ * UIProcess/API/gtk/tests/TestLoaderClient.cpp:
+ (testWebViewHistoryLoad):
+ (serverCallback):
+ (beforeAll):
+
2012-08-02 Andras Becsi <[email protected]>
[Qt][WK2] Click, mouse and links rely on touch mocking.
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp 2012-08-02 15:01:14 UTC (rev 124456)
@@ -65,16 +65,7 @@
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)
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp 2012-08-02 15:01:14 UTC (rev 124456)
@@ -243,6 +243,11 @@
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
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h 2012-08-02 15:01:14 UTC (rev 124456)
@@ -29,6 +29,7 @@
void webkitWebResourceNotifyProgress(WebKitWebResource*, guint64 bytesReceived);
void webkitWebResourceFinished(WebKitWebResource*);
void webkitWebResourceFailed(WebKitWebResource*, GError*);
+WKFrameRef webkitWebResourceGetFrame(WebKitWebResource*);
#endif // WebKitWebResourcePrivate_h
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2012-08-02 15:01:14 UTC (rev 124456)
@@ -124,6 +124,10 @@
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 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 webkitWebViewFinalize(GObject* object)
{
- WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(object)->priv;
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
+ WebKitWebViewPrivate* priv = webView->priv;
if (priv->_javascript_GlobalContext)
JSGlobalContextRelease(priv->_javascript_GlobalContext);
@@ -391,7 +404,8 @@
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 @@
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)
@@ -1269,6 +1331,24 @@
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 @@
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);
}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.cpp 2012-08-02 15:01:14 UTC (rev 124456)
@@ -35,10 +35,17 @@
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 @@
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();
+}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/LoadTrackingTest.h 2012-08-02 15:01:14 UTC (rev 124456)
@@ -44,6 +44,8 @@
void loadPlainText(const char* plainText);
void loadRequest(WebKitURIRequest*);
void reload();
+ void goBack();
+ void goForward();
void setRedirectURI(const char* uri) { m_redirectURI = uri; }
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp (124455 => 124456)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp 2012-08-02 14:42:30 UTC (rev 124455)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestLoaderClient.cpp 2012-08-02 15:01:14 UTC (rev 124456)
@@ -144,6 +144,26 @@
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 @@
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 @@
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.