diff options
Diffstat (limited to 'Source/WebKit2/UIProcess')
50 files changed, 917 insertions, 351 deletions
diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp index c7e5f029c..567548f5d 100644 --- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp @@ -32,7 +32,7 @@ #include "WebContext.h" #include "WebContextMenuProxy.h" #include "WebPageProxy.h" -#include "ewk_private.h" +#include "ewk_view_private.h" using namespace WebCore; @@ -186,6 +186,13 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool) notImplemented(); } +#if ENABLE(TOUCH_EVENTS) +void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) +{ + notImplemented(); +} +#endif + PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy*) { notImplemented(); diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h index 0858fc33d..a4dcd93e3 100644 --- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h @@ -77,6 +77,9 @@ private: virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&); virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool); +#if ENABLE(TOUCH_EVENTS) + virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled); +#endif virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*); virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*); diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_private.h b/Source/WebKit2/UIProcess/API/efl/ewk_view_private.h index d331d996f..e776725cc 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_private.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view_private.h @@ -18,8 +18,8 @@ * */ -#ifndef ewk_private_h -#define ewk_private_h +#ifndef ewk_view_private_h +#define ewk_view_private_h #include <Evas.h> @@ -31,4 +31,4 @@ class IntSize; void ewk_view_display(Evas_Object* ewkView, const WebCore::IntRect& rect); void ewk_view_image_data_set(Evas_Object* ewkView, void* imageData, const WebCore::IntSize& size); -#endif // ewk_private_h +#endif // ewk_view_private_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp index 018f08d3d..61d316f6c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp @@ -20,8 +20,10 @@ #include "config.h" #include "WebKitDownload.h" +#include "DownloadProxy.h" #include "WebKitDownloadPrivate.h" #include "WebKitMarshal.h" +#include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include <WebCore/ErrorsGtk.h> #include <WebCore/ResourceResponse.h> @@ -53,6 +55,7 @@ enum { struct _WebKitDownloadPrivate { WKRetainPtr<WKDownloadRef> wkDownload; + GRefPtr<WebKitURIRequest> request; GRefPtr<WebKitURIResponse> response; CString destinationURI; guint64 currentSize; @@ -360,6 +363,25 @@ void webkitDownloadDestinationCreated(WebKitDownload* download, const CString& d } /** + * webkit_download_get_request: + * @download: a #WebKitDownload + * + * Retrieves the #WebKitURIRequest object that backs the download + * process. + * + * Returns: (transfer none): the #WebKitURIRequest of @download + */ +WebKitURIRequest* webkit_download_get_request(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0); + + WebKitDownloadPrivate* priv = download->priv; + if (!priv->request) + priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(priv->wkDownload.get())->request())); + return download->priv->request.get(); +} + +/** * webkit_download_get_destination: * @download: a #WebKitDownload * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h index b6c51fea5..b4a2d3bab 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h @@ -26,6 +26,7 @@ #include <glib-object.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitURIResponse.h> G_BEGIN_DECLS @@ -57,6 +58,9 @@ struct _WebKitDownloadClass { WEBKIT_API GType webkit_download_get_type (void); +WEBKIT_API WebKitURIRequest * +webkit_download_get_request (WebKitDownload *download); + WEBKIT_API const gchar * webkit_download_get_destination (WebKitDownload *download); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp index 9476255c8..158c7fc42 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp @@ -147,7 +147,8 @@ void attachLoaderClientToView(WebKitWebView* webView) 0, // didDetectXSSForFrame 0, // didFirstVisuallyNonEmptyLayoutForFrame 0, // willGoToBackForwardListItem - 0 // interactionOccurredWhileProcessUnresponsive + 0, // interactionOccurredWhileProcessUnresponsive + 0, // pluginDidFail }; WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); WKPageSetPageLoaderClient(wkPage, &wkLoaderClient); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp index 9f78c9cbf..2548d7b72 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp @@ -191,6 +191,7 @@ void attachUIClientToView(WebKitWebView* webView) createNewPage, mouseDidMoveOverElement, 0, // decidePolicyForNotificationPermissionRequest + 0, // unavailablePluginButtonClicked }; WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); WKPageSetPageUIClient(wkPage, &wkUIClient); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp index 174bf12f8..93f83c2de 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp @@ -30,7 +30,8 @@ enum { PROP_URI, PROP_STATUS_CODE, - PROP_CONTENT_LENGTH + PROP_CONTENT_LENGTH, + PROP_MIME_TYPE }; using namespace WebCore; @@ -40,6 +41,7 @@ G_DEFINE_TYPE(WebKitURIResponse, webkit_uri_response, G_TYPE_OBJECT) struct _WebKitURIResponsePrivate { WebCore::ResourceResponse resourceResponse; CString uri; + CString mimeType; }; static void webkitURIResponseFinalize(GObject* object) @@ -62,6 +64,9 @@ static void webkitURIResponseGetProperty(GObject* object, guint propId, GValue* case PROP_CONTENT_LENGTH: g_value_set_uint64(value, webkit_uri_response_get_content_length(response)); break; + case PROP_MIME_TYPE: + g_value_set_string(value, webkit_uri_response_get_mime_type(response)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -112,6 +117,19 @@ static void webkit_uri_response_class_init(WebKitURIResponseClass* responseClass 0, G_MAXUINT64, 0, WEBKIT_PARAM_READABLE)); + /** + * WebKitURIResponse:mime-type: + * + * The MIME type of the response. + */ + g_object_class_install_property(objectClass, + PROP_MIME_TYPE, + g_param_spec_string("mime-type", + _("MIME Type"), + _("The MIME type of the response"), + 0, + WEBKIT_PARAM_READABLE)); + g_type_class_add_private(responseClass, sizeof(WebKitURIResponsePrivate)); } @@ -170,6 +188,20 @@ guint64 webkit_uri_response_get_content_length(WebKitURIResponse* response) return response->priv->resourceResponse.expectedContentLength(); } +/** + * webkit_uri_response_get_mime_type: + * @response: a #WebKitURIResponse + * + * Returns: the MIME type of the #WebKitURIResponse + */ +const gchar* webkit_uri_response_get_mime_type(WebKitURIResponse* response) +{ + g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), 0); + + response->priv->mimeType = response->priv->resourceResponse.mimeType().utf8(); + return response->priv->mimeType.data(); +} + WebKitURIResponse* webkitURIResponseCreateForResourceResponse(const WebCore::ResourceResponse& resourceResponse) { WebKitURIResponse* uriResponse = WEBKIT_URI_RESPONSE(g_object_new(WEBKIT_TYPE_URI_RESPONSE, NULL)); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h index cfbe4d819..0cc6c8959 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h @@ -64,6 +64,9 @@ webkit_uri_response_get_status_code (WebKitURIResponse *response); WEBKIT_API guint64 webkit_uri_response_get_content_length (WebKitURIResponse *response); +WEBKIT_API const gchar * +webkit_uri_response_get_mime_type (WebKitURIResponse *response); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp index 77ef6c1de..938f95fd1 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp @@ -33,9 +33,11 @@ #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" #include "WebKitResourceLoadClient.h" +#include "WebKitResponsePolicyDecision.h" #include "WebKitScriptDialogPrivate.h" #include "WebKitSettingsPrivate.h" #include "WebKitUIClient.h" +#include "WebKitURIResponsePrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebInspectorPrivate.h" #include "WebKitWebResourcePrivate.h" @@ -190,9 +192,25 @@ static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDi return TRUE; } -static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType) +static gboolean webkitWebViewDecidePolicy(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType) { - webkit_policy_decision_use(decision); + if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) { + webkit_policy_decision_use(decision); + return TRUE; + } + + WebKitURIResponse* response = webkit_response_policy_decision_get_response(WEBKIT_RESPONSE_POLICY_DECISION(decision)); + const ResourceResponse resourceResponse = webkitURIResponseGetResourceResponse(response); + if (resourceResponse.isAttachment()) { + webkit_policy_decision_download(decision); + return TRUE; + } + + if (webkit_web_view_can_show_mime_type(webView, webkit_uri_response_get_mime_type(response))) + webkit_policy_decision_use(decision); + else + webkit_policy_decision_ignore(decision); + return TRUE; } @@ -509,6 +527,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * * By default, if the signal is not handled, a stock error page will be displayed. * You need to handle the signal if you want to provide your own error page. + * + * Returns: %TRUE to stop other handlers from being invoked for the event. + * %FALSE to propagate the event further. */ signals[LOAD_FAILED] = g_signal_new("load-failed", @@ -1754,7 +1775,7 @@ void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const c * * Finish an asynchronous operation started with webkit_web_view_can_execute_editing_command(). * - * Returns: %TRUE if a selection can be cut or %FALSE otherwise + * Returns: %TRUE if the editing command can be executed or %FALSE otherwise */ gboolean webkit_web_view_can_execute_editing_command_finish(WebKitWebView* webView, GAsyncResult* result, GError** error) { @@ -1918,13 +1939,13 @@ void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, * context = webkit_javascript_result_get_global_context (js_result); * value = webkit_javascript_result_get_value (js_result); * if (JSValueIsString (context, value)) { - * JSStringRef *js_str_value; - * gchar *str_value; - * gsize str_length; + * JSStringRef js_str_value; + * gchar *str_value; + * gsize str_length; * - * js_str_value = JSValueToStringCopy (context, value, NULL)); + * js_str_value = JSValueToStringCopy (context, value, NULL); * str_length = JSStringGetMaximumUTF8CStringSize (js_str_value); - * str_value = (gchar *)g_malloc (str_length)); + * str_value = (gchar *)g_malloc (str_length); * JSStringGetUTF8CString (js_str_value, str_value, str_length); * JSStringRelease (js_str_value); * g_print ("Script result: %s\n", str_value); @@ -1942,7 +1963,7 @@ void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, * gchar *script; * * script = g_strdup_printf ("window.document.getElementById('%s').href;", link_id); - * webkit_web_view_run_javascript (web_view, script, web_view_javascript_finished, NULL); + * webkit_web_view_run_javascript (web_view, script, NULL, web_view_javascript_finished, NULL); * g_free (script); * } * </programlisting></informalexample> @@ -2023,3 +2044,21 @@ WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView) return webView->priv->inspector.get(); } + +/** + * webkit_web_view_can_show_mime_type: + * @web_view: a #WebKitWebView + * @mime_type: a MIME type + * + * Whether or not a MIME type can be displayed in @web_view. + * + * Returns: %TRUE if the MIME type @mime_type can be displayed or %FALSE otherwise + */ +gboolean webkit_web_view_can_show_mime_type(WebKitWebView* webView, const char* mimeType) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + g_return_val_if_fail(mimeType, FALSE); + + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + return page->canShowMIMEType(String::fromUTF8(mimeType)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h index 7f9fb9e36..716fbbd08 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h @@ -306,6 +306,10 @@ webkit_web_view_get_subresources (WebKitWebView *w WEBKIT_API WebKitWebInspector * webkit_web_view_get_inspector (WebKitWebView *web_view); +WEBKIT_API gboolean +webkit_web_view_can_show_mime_type (WebKitWebView *web_view, + const gchar *mime_type); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp index 4faa75fb0..f8308aa14 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp @@ -675,8 +675,8 @@ void webkitWebViewBaseStartDrag(WebKitWebViewBase* webViewBase, const DragData& { WebKitWebViewBasePrivate* priv = webViewBase->priv; - RefPtr<DataObjectGtk> dataObject(dragData.platformData()); - GRefPtr<GtkTargetList> targetList(PasteboardHelper::defaultPasteboardHelper()->targetListForDataObject(dataObject.get())); + RefPtr<DataObjectGtk> dataObject = adoptRef(dragData.platformData()); + GRefPtr<GtkTargetList> targetList = adoptGRef(PasteboardHelper::defaultPasteboardHelper()->targetListForDataObject(dataObject.get())); GOwnPtr<GdkEvent> currentEvent(gtk_get_current_event()); GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(webViewBase), targetList.get(), diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt index 4251cc4a6..6dde0866d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt @@ -95,6 +95,7 @@ webkit_web_view_get_inspector 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 <SUBSECTION WebKitJavascriptResult> WebKitJavascriptResult @@ -302,6 +303,7 @@ WebKitURIResponse webkit_uri_response_get_uri webkit_uri_response_get_status_code webkit_uri_response_get_content_length +webkit_uri_response_get_mime_type <SUBSECTION Standard> WebKitURIResponseClass @@ -346,6 +348,7 @@ webkit_window_properties_get_type <SECTION> <FILE>WebKitDownload</FILE> WebKitDownload +webkit_download_get_request webkit_download_get_destination webkit_download_set_destination webkit_download_get_response diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp index a119e4477..acec9ece1 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp @@ -88,6 +88,7 @@ public: static void downloadStartedCallback(WebKitWebContext* context, WebKitDownload* download, DownloadTest* test) { + g_assert(webkit_download_get_request(download)); test->started(download); g_signal_connect(download, "notify::response", G_CALLBACK(receivedResponseCallback), test); g_signal_connect(download, "created-destination", G_CALLBACK(createdDestinationCallback), test); @@ -191,6 +192,10 @@ static void testDownloadLocalFile(DownloadTest* test, gconstpointer) g_assert_cmpint(events[3], ==, DownloadTest::ReceivedData); g_assert_cmpint(events[4], ==, DownloadTest::Finished); + WebKitURIRequest* request = webkit_download_get_request(download.get()); + g_assert(request); + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, sourceURI.get()); + g_assert_cmpint(test->m_downloadSize, ==, g_file_info_get_size(sourceInfo.get())); g_assert(webkit_download_get_destination(download.get())); g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1); @@ -328,6 +333,11 @@ static void testDownloadRemoteFile(DownloadTest* test, gconstpointer) g_assert_cmpint(events[4], ==, DownloadTest::Finished); events.clear(); + WebKitURIRequest* request = webkit_download_get_request(download.get()); + g_assert(request); + CString requestURI = kServer->getURIForPath("/test.pdf"); + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, requestURI.data()); + g_assert(webkit_download_get_destination(download.get())); g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1); test->checkDestinationAndDeleteFile(download.get(), kServerSuggestedFilename); diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp index 39841756d..7de95e0f0 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp @@ -300,13 +300,11 @@ public: g_main_loop_run(m_mainLoop); } - int waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse() + WebKitURIResponse* waitUntilResourceLoadFinsihedAndReturnURIResponse() { waitUntilResourceLoadFinsihed(); g_assert(m_resource); - WebKitURIResponse* response = webkit_web_resource_get_response(m_resource.get()); - g_assert(response); - return webkit_uri_response_get_status_code(response); + return webkit_web_resource_get_response(m_resource.get()); } GRefPtr<WebKitWebResource> m_resource; @@ -355,33 +353,48 @@ static void testWebResourceResponse(SingleResourceLoadTest* test, gconstpointer) { // No cached resource: First load. test->loadURI(kServer->getURIForPath("/javascript.html").data()); - gint statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse(); - g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK); + WebKitURIResponse* response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // No cached resource: Second load. test->loadURI(kServer->getURIForPath("/javascript.html").data()); - statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse(); - g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // No cached resource: Reload. webkit_web_view_reload(test->m_webView); - statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse(); - g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // Cached resource: First load. test->loadURI(kServer->getURIForPath("/image.html").data()); - statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse(); - g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // Cached resource: Second load. test->loadURI(kServer->getURIForPath("/image.html").data()); - statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse(); - g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // Cached resource: Reload. webkit_web_view_reload(test->m_webView); - statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse(); - g_assert_cmpint(statusCode, ==, SOUP_STATUS_NOT_MODIFIED); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_NOT_MODIFIED); +} + +static void testWebResourceMimeType(SingleResourceLoadTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/javascript.html").data()); + WebKitURIResponse* response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/javascript"); + + test->loadURI(kServer->getURIForPath("/image.html").data()); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "image/vnd.microsoft.icon"); + + test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); + response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/css"); } class ResourceURITrackingTest: public SingleResourceLoadTest { @@ -555,6 +568,7 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char* addCacheHTTPHeadersToResponse(message); } else if (g_str_equal(path, "/javascript.js")) { soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kJavascript, strlen(kJavascript)); + soup_message_headers_append(message->response_headers, "Content-Type", "text/javascript"); } else if (g_str_equal(path, "/blank.ico")) { GOwnPtr<char> filePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), path, NULL)); char* contents; @@ -569,6 +583,7 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char* " padding: 0px;" "}"; soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, simpleCSS, strlen(simpleCSS)); + soup_message_headers_append(message->response_headers, "Content-Type", "text/css"); } else if (g_str_equal(path, "/redirected.css")) { soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); soup_message_headers_append(message->response_headers, "Location", "/simple-style.css"); @@ -585,6 +600,7 @@ void beforeAll() ResourcesTest::add("WebKitWebView", "resources", testWebViewResources); SingleResourceLoadTest::add("WebKitWebResource", "loading", testWebResourceLoading); SingleResourceLoadTest::add("WebKitWebResource", "response", testWebResourceResponse); + SingleResourceLoadTest::add("WebKitWebResource", "mime-type", testWebResourceMimeType); ResourceURITrackingTest::add("WebKitWebResource", "active-uri", testWebResourceActiveURI); ResourcesTest::add("WebKitWebResource", "get-data", testWebResourceGetData); ResourcesTest::add("WebKitWebView", "replaced-content", testWebViewResourcesReplacedContent); diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp index e4c60bebc..6ede533d4 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp @@ -706,6 +706,20 @@ static void testWebViewFullScreen(FullScreenClientTest* test, gconstpointer) g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Leave); } +static void testWebViewCanShowMIMEType(WebViewTest* test, gconstpointer) +{ + // Supported MIME types. + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "text/html")); + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "text/plain")); + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "image/jpeg")); + + // Unsupported MIME types. + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "text/vcard")); + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "application/pdf")); + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "application/zip")); + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "application/octet-stream")); +} + void beforeAll() { WebViewTest::add("WebKitWebView", "default-context", testWebViewDefaultContext); @@ -720,6 +734,7 @@ void beforeAll() WebViewTest::add("WebKitWebView", "run-javascript", testWebViewRunJavaScript); FileChooserTest::add("WebKitWebView", "file-chooser-request", testWebViewFileChooserRequest); FullScreenClientTest::add("WebKitWebView", "fullscreen", testWebViewFullScreen); + WebViewTest::add("WebKitWebView", "can-show-mime-type", testWebViewCanShowMIMEType); } void afterAll() diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h index b58210a80..cc5c349e2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h @@ -36,9 +36,11 @@ #include <webkit2/WebKitHitTestResult.h> #include <webkit2/WebKitJavascriptResult.h> #include <webkit2/WebKitMimeInfo.h> +#include <webkit2/WebKitNavigationPolicyDecision.h> #include <webkit2/WebKitPermissionRequest.h> #include <webkit2/WebKitPlugin.h> #include <webkit2/WebKitPrintOperation.h> +#include <webkit2/WebKitResponsePolicyDecision.h> #include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp index 178e2dade..e0d6012d2 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp @@ -124,7 +124,7 @@ void QQuickWebPage::setContentsScale(qreal scale) ASSERT(scale > 0); d->contentsScale = scale; d->updateSize(); - emit d->viewportItem->experimental()->test()->contentsScaleCommitted(); + emit d->viewportItem->experimental()->test()->contentsScaleChanged(); } qreal QQuickWebPage::contentsScale() const diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index 9d77171cc..5b43e337d 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -44,6 +44,7 @@ #include "qquickwebpage_p_p.h" #include "qquickwebview_p_p.h" #include "qwebdownloaditem_p_p.h" +#include "qwebiconimageprovider_p.h" #include "qwebkittest_p.h" #include "qwebloadrequest_p.h" #include "qwebnavigationhistory_p.h" @@ -54,13 +55,16 @@ #include <JavaScriptCore/JSBase.h> #include <JavaScriptCore/JSRetainPtr.h> #include <QDateTime> +#include <QtCore/QFile> #include <QtQml/QJSValue> +#include <QtQuick/QQuickView> #include <WKOpenPanelResultListener.h> #include <WKSerializedScriptValue.h> #include <WebCore/IntPoint.h> #include <WebCore/IntRect.h> #include <wtf/Assertions.h> #include <wtf/MainThread.h> +#include <wtf/Vector.h> #include <wtf/text/WTFString.h> using namespace WebCore; @@ -303,7 +307,7 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(toAPI(webPageProxy.get()))); QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); - QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl))); + QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QString)), q_ptr, SLOT(_q_onIconChangedForPageURL(QString))); // Any page setting should preferrable be set before creating the page. webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true); @@ -373,9 +377,6 @@ void QQuickWebViewPrivate::loadProgressDidChange(int loadProgress) { Q_Q(QQuickWebView); - if (!loadProgress) - setIcon(QUrl()); - m_loadProgress = loadProgress; emit q->loadProgressChanged(); @@ -418,16 +419,6 @@ void QQuickWebViewPrivate::setNeedsDisplay() q->page()->update(); } -void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL) -{ - Q_Q(QQuickWebView); - - if (q->url() != pageURL) - return; - - setIcon(iconURL); -} - void QQuickWebViewPrivate::processDidCrash() { Q_Q(QQuickWebView); @@ -452,6 +443,7 @@ void QQuickWebViewPrivate::didRelaunchProcess() webPageProxy->drawingArea()->setSize(viewSize(), IntSize()); updateViewportSize(); + updateUserScripts(); } PassOwnPtr<DrawingAreaProxy> QQuickWebViewPrivate::createDrawingAreaProxy() @@ -480,8 +472,38 @@ void QQuickWebViewPrivate::_q_onVisibleChanged() void QQuickWebViewPrivate::_q_onUrlChanged() { + updateIcon(); +} + +void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QString& pageUrl) +{ + if (pageUrl != QString(m_currentUrl)) + return; + + updateIcon(); +} + +/* Called either when the url changes, or when the icon for the current page changes */ +void QQuickWebViewPrivate::updateIcon() +{ Q_Q(QQuickWebView); - context->iconDatabase()->requestIconForPageURL(q->url()); + + QQuickView* view = qobject_cast<QQuickView*>(q->canvas()); + if (!view) + return; + + QWebIconImageProvider* provider = static_cast<QWebIconImageProvider*>( + view->engine()->imageProvider(QWebIconImageProvider::identifier())); + if (!provider) + return; + + WTF::String iconUrl = provider->iconURLForPageURLInContext(m_currentUrl, context.get()); + + if (iconUrl == m_iconUrl) + return; + + m_iconUrl = iconUrl; + emit q->iconChanged(); } void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem) @@ -641,31 +663,6 @@ void QQuickWebViewPrivate::addAttachedPropertyTo(QObject* object) attached->setView(q); } -void QQuickWebViewPrivate::setIcon(const QUrl& iconURL) -{ - Q_Q(QQuickWebView); - if (m_iconURL == iconURL) - return; - - if (!webPageProxy->mainFrame()) - return; - - String oldPageURL = QUrl::fromPercentEncoding(m_iconURL.encodedFragment()); - String newPageURL = webPageProxy->mainFrame()->url(); - - if (oldPageURL != newPageURL) { - QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); - if (!oldPageURL.isEmpty()) - iconDatabase->releaseIconForPageURL(oldPageURL); - - if (!newPageURL.isEmpty()) - iconDatabase->retainIconForPageURL(newPageURL); - } - - m_iconURL = iconURL; - emit q->iconChanged(); -} - bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const { return m_navigatorQtObjectEnabled; @@ -679,6 +676,52 @@ void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled) context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled); } +static QString readUserScript(const QUrl& url) +{ + QString path; + if (url.isLocalFile()) + path = url.toLocalFile(); + else if (url.scheme() == QLatin1String("qrc")) + path = QStringLiteral(":") + url.path(); + else { + qWarning("QQuickWebView: Couldn't open '%s' as user script because only file:/// and qrc:/// URLs are supported.", qPrintable(url.toString())); + return QString(); + } + + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning("QQuickWebView: Couldn't open '%s' as user script due to error '%s'.", qPrintable(url.toString()), qPrintable(file.errorString())); + return QString(); + } + + QString contents = QString::fromUtf8(file.readAll()); + if (contents.isEmpty()) + qWarning("QQuickWebView: Ignoring '%s' as user script because file is empty.", qPrintable(url.toString())); + + return contents; +} + +void QQuickWebViewPrivate::updateUserScripts() +{ + Vector<String> scripts; + scripts.reserveCapacity(userScripts.size()); + + for (unsigned i = 0; i < userScripts.size(); ++i) { + const QUrl& url = userScripts.at(i); + if (!url.isValid()) { + qWarning("QQuickWebView: Couldn't open '%s' as user script because URL is invalid.", qPrintable(url.toString())); + continue; + } + + QString contents = readUserScript(url); + if (contents.isEmpty()) + continue; + scripts.append(String(contents)); + } + + webPageProxy->setUserScripts(scripts); +} + QPointF QQuickWebViewPrivate::contentPos() const { Q_Q(const QQuickWebView); @@ -727,12 +770,6 @@ void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String& QQuickWebViewLegacyPrivate::QQuickWebViewLegacyPrivate(QQuickWebView* viewport) : QQuickWebViewPrivate(viewport) { - // Default values for the Legacy view. - attributes.devicePixelRatio = 1; - attributes.initialScale = 1; - attributes.minimumScale = 1; - attributes.maximumScale = 1; - attributes.userScalable = 0; } void QQuickWebViewLegacyPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef) @@ -782,7 +819,8 @@ void QQuickWebViewLegacyPrivate::setZoomFactor(qreal factor) QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport) : QQuickWebViewPrivate(viewport) - , pageIsSuspended(true) + , pageIsSuspended(false) + , lastCommittedScale(-1) { // Disable mouse events on the flickable web view so we do not // select text during pan gestures on platforms which send both @@ -823,30 +861,7 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportAttributes& newAttributes) { - Q_Q(QQuickWebView); - - // FIXME: Revise these when implementing fit-to-width. - WebCore::ViewportAttributes attr = newAttributes; - WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr); - - // FIXME: Resetting here can reset more than needed. For instance it will end deferrers. - // This needs to be revised at some point. - interactionEngine->reset(); - - interactionEngine->setContentToDevicePixelRatio(attr.devicePixelRatio); - - interactionEngine->setAllowsUserScaling(!!attr.userScalable); - interactionEngine->setCSSScaleBounds(attr.minimumScale, attr.maximumScale); - - if (!interactionEngine->hadUserInteraction() && !pageIsSuspended) - interactionEngine->setCSSScale(attr.initialScale); - - this->attributes = attr; - emit q->experimental()->test()->viewportChanged(); - - // If the web app successively changes the viewport on purpose - // it wants to be in control and we should disable animations. - interactionEngine->setItemRectVisible(interactionEngine->nearestValidBounds()); + interactionEngine->viewportAttributesChanged(newAttributes); } void QQuickWebViewFlickablePrivate::updateViewportSize() @@ -876,14 +891,19 @@ void QQuickWebViewFlickablePrivate::_q_onInformVisibleContentChange(const QPoint if (!drawingArea) return; - const QRect visibleRect(visibleContentsRect()); + QRectF accurateVisibleRect(q->boundingRect()); + accurateVisibleRect.translate(contentPos()); + + if (accurateVisibleRect == drawingArea->contentsRect()) + return; + float scale = pageView->contentsScale(); - emit q->experimental()->test()->contentsScaleChanged(); + if (scale != lastCommittedScale) + emit q->experimental()->test()->contentsScaleCommitted(); + lastCommittedScale = scale; - QRectF accurateVisibleRect(q->boundingRect()); - accurateVisibleRect.translate(contentPos()); - drawingArea->setVisibleContentsRect(visibleRect, scale, trajectoryVector, FloatPoint(accurateVisibleRect.x(), accurateVisibleRect.y())); + drawingArea->setVisibleContentsRect(QRect(visibleContentsRect()), scale, trajectoryVector, FloatPoint(accurateVisibleRect.x(), accurateVisibleRect.y())); // Ensure that updatePaintNode is always called before painting. pageView->update(); @@ -908,38 +928,17 @@ void QQuickWebViewFlickablePrivate::_q_resume() void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos) { - interactionEngine->pagePositionRequest(pos); + interactionEngine->pageContentPositionRequest(pos); } void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize) { Q_Q(QQuickWebView); - QSize viewportSize = q->boundingRect().size().toSize(); pageView->setContentsSize(newSize); // emits contentsSizeChanged() - - float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(attributes, viewportSize, newSize); - - bool scaleCommitNotified = false; - - if (!qFuzzyCompare(minimumScale, attributes.minimumScale)) { - interactionEngine->setCSSScaleBounds(minimumScale, attributes.maximumScale); - emit q->experimental()->test()->viewportChanged(); - - if (!interactionEngine->hadUserInteraction() && !pageIsSuspended) { - // Emits contentsScaleCommitted(); - scaleCommitNotified = true; - interactionEngine->setCSSScale(minimumScale); - } - } - - // Emit for testing purposes, so that it can be verified that - // we didn't do scale adjustment. - if (!scaleCommitNotified) - emit q->experimental()->test()->contentsScaleCommitted(); + interactionEngine->pageContentsSizeChanged(newSize, q->boundingRect().size().toSize()); } - /*! \qmlsignal WebView::onNavigationRequested(WebNavigationRequest request) @@ -1296,6 +1295,22 @@ void QQuickWebViewExperimental::evaluateJavaScript(const QString& script, const d_ptr->webPageProxy.get()->runJavaScriptInMainFrame(script, ScriptValueCallback::create(closure, javaScriptCallback)); } +QList<QUrl> QQuickWebViewExperimental::userScripts() const +{ + Q_D(const QQuickWebView); + return d->userScripts; +} + +void QQuickWebViewExperimental::setUserScripts(const QList<QUrl>& userScripts) +{ + Q_D(QQuickWebView); + if (d->userScripts == userScripts) + return; + d->userScripts = userScripts; + d->updateUserScripts(); + emit userScriptsChanged(); +} + QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QQmlListProperty<QQuickUrlSchemeDelegate>* property, int index) { const QObjectList children = property->object->children(); @@ -1494,7 +1509,7 @@ void QQuickWebView::emitUrlChangeIfNeeded() QUrl QQuickWebView::icon() const { Q_D(const QQuickWebView); - return d->m_iconURL; + return QUrl(d->m_iconUrl); } /*! diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index f33c6e654..cf469fb1e 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -212,11 +212,12 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged()); Q_PRIVATE_SLOT(d_func(), void _q_onUrlChanged()); Q_PRIVATE_SLOT(d_func(), void _q_onReceivedResponseFromDownload(QWebDownloadItem*)); - Q_PRIVATE_SLOT(d_func(), void _q_onIconChangedForPageURL(const QUrl&, const QUrl&)); + Q_PRIVATE_SLOT(d_func(), void _q_onIconChangedForPageURL(const QString&)); // Hides QObject::d_ptr allowing us to use the convenience macros. QScopedPointer<QQuickWebViewPrivate> d_ptr; QQuickWebViewExperimental* m_experimental; + friend class QWebKitTest; friend class WebKit::QtViewportInteractionEngine; friend class WebKit::QtWebPageLoadClient; friend class WebKit::QtWebPagePolicyClient; @@ -268,6 +269,7 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(QQmlListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates) Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent NOTIFY userAgentChanged) Q_PROPERTY(double devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged) + Q_PROPERTY(QList<QUrl> userScripts READ userScripts WRITE setUserScripts NOTIFY userScriptsChanged) Q_ENUMS(NavigationRequestActionExperimental) public: @@ -300,6 +302,8 @@ public: void setUserAgent(const QString& userAgent); double devicePixelRatio() const; void setDevicePixelRatio(double); + QList<QUrl> userScripts() const; + void setUserScripts(const QList<QUrl>& userScripts); QWebKitTest* test(); @@ -353,6 +357,7 @@ Q_SIGNALS: void devicePixelRatioChanged(); void enterFullScreenRequested(); void exitFullScreenRequested(); + void userScriptsChanged(); private: QQuickWebView* q_ptr; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index 572a7f226..69afc2d54 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -103,7 +103,7 @@ public: void _q_onVisibleChanged(); void _q_onUrlChanged(); void _q_onReceivedResponseFromDownload(QWebDownloadItem*); - void _q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURLString); + void _q_onIconChangedForPageURL(const QString&); void chooseFiles(WKOpenPanelResultListenerRef, const QStringList& selectedFileNames, WebKit::QtWebPageUIClient::FileChooserType); quint64 exceededDatabaseQuota(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage); @@ -118,12 +118,12 @@ public: void setRenderToOffscreenBuffer(bool enable) { m_renderToOffscreenBuffer = enable; } void setTransparentBackground(bool); void addAttachedPropertyTo(QObject*); - void setIcon(const QUrl&); bool navigatorQtObjectEnabled() const; bool renderToOffscreenBuffer() const { return m_renderToOffscreenBuffer; } bool transparentBackground() const; void setNavigatorQtObjectEnabled(bool); + void updateUserScripts(); QPointF contentPos() const; void setContentPos(const QPointF&); @@ -132,6 +132,8 @@ public: void setDialogActive(bool active) { m_dialogActive = active; } + void updateIcon(); + // PageClient. WebCore::IntSize viewSize() const; void didReceiveMessageFromNavigatorQtObject(const String& message); @@ -190,14 +192,14 @@ protected: QQmlComponent* filePicker; QQmlComponent* databaseQuotaDialog; - WebCore::ViewportAttributes attributes; + QList<QUrl> userScripts; bool m_useDefaultContentItemSize; bool m_navigatorQtObjectEnabled; bool m_renderToOffscreenBuffer; bool m_dialogActive; bool m_allowAnyHTTPSCertificateForLocalHost; - QUrl m_iconURL; + WTF::String m_iconUrl; int m_loadProgress; WTF::String m_currentUrl; }; @@ -239,6 +241,7 @@ public: private: QScopedPointer<WebKit::QtViewportInteractionEngine> interactionEngine; bool pageIsSuspended; + float lastCommittedScale; }; #endif // qquickwebview_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp index 71342a1e3..63dce28d0 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp @@ -24,6 +24,7 @@ #include "QtWebIconDatabaseClient.h" #include <QtCore/QUrl> #include <QtGui/QImage> +#include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> using namespace WebKit; @@ -37,24 +38,52 @@ QWebIconImageProvider::~QWebIconImageProvider() { } -QImage QWebIconImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) +WTF::String QWebIconImageProvider::iconURLForPageURLInContext(const WTF::String &pageURL, QtWebContext* context) { - QString decodedIconUrl = id; - decodedIconUrl.remove(0, decodedIconUrl.indexOf('#') + 1); - String pageURL = QString::fromUtf8(QUrl(decodedIconUrl).toEncoded()); + QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); + WTF::String iconURL = iconDatabase->iconForPageURL(pageURL); + + if (iconURL.isEmpty()) + return String(); + + QUrl url; + url.setScheme(QStringLiteral("image")); + url.setHost(QWebIconImageProvider::identifier()); + + QString path; + path.append(QLatin1Char('/')); + path.append(QString::number(context->contextID())); + path.append(QLatin1Char('/')); + path.append(QString::number(WTF::StringHash::hash(iconURL))); + url.setPath(path); + + // FIXME: Use QUrl::DecodedMode when landed in Qt + url.setFragment(QString::fromLatin1(QByteArray(QString(pageURL).toUtf8()).toBase64())); + + // FIXME: We can't know when the icon url is no longer in use, + // so we never release these icons. At some point we might want + // to introduce expiry of icons to elevate this issue. + iconDatabase->retainIconForPageURL(pageURL); + return url.toString(QUrl::FullyEncoded); +} + +QImage QWebIconImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) +{ // The string identifier has the leading image://webicon/ already stripped, so we just // need to truncate from the first slash to get the context id. - QString contextIDAsString = id; - contextIDAsString.truncate(contextIDAsString.indexOf(QLatin1Char('/'))); + QString contextIDString = id.left(id.indexOf(QLatin1Char('/'))); bool ok = false; - uint64_t contextId = contextIDAsString.toUInt(&ok); + uint64_t contextId = contextIDString.toUInt(&ok); if (!ok) return QImage(); + QtWebContext* context = QtWebContext::contextByID(contextId); if (!context) return QImage(); + QString pageURL = QString::fromUtf8(QByteArray::fromBase64(id.midRef(id.indexOf('#') + 1).toLatin1())); + QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); QImage icon = requestedSize.isValid() ? iconDatabase->iconImageForPageURL(pageURL, requestedSize) : iconDatabase->iconImageForPageURL(pageURL); ASSERT(!icon.isNull()); diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h index a54008a2c..7efe21a14 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h @@ -21,13 +21,23 @@ #define qwebiconimageprovider_p_h #include "qwebkitglobal.h" +#include <QString> #include <QtQuick/QQuickImageProvider> +#include <wtf/text/WTFString.h> + +namespace WebKit { + class QtWebContext; +} class QWEBKIT_EXPORT QWebIconImageProvider : public QQuickImageProvider { public: QWebIconImageProvider(); ~QWebIconImageProvider(); - QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize); + + static QString identifier() { return QStringLiteral("webicon"); } + + WTF::String iconURLForPageURLInContext(const WTF::String& pageURL, WebKit::QtWebContext* context); + virtual QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize); }; #endif diff --git a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp index 529df01eb..e0a441c0e 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp @@ -22,9 +22,10 @@ #include "qwebkittest_p.h" #include "QtViewportInteractionEngine.h" -#include "QtWebPageEventHandler.h" -#include "qquickwebview_p.h" #include "qquickwebview_p_p.h" +#include "qwindowsysteminterface_qpa.h" +#include <QMutableListIterator> +#include <QTouchEvent> using namespace WebKit; @@ -43,41 +44,71 @@ static QTouchEvent::TouchPoint touchPoint(qreal x, qreal y) QPointF localPos(x, y); QTouchEvent::TouchPoint point; + point.setId(1); point.setLastPos(localPos); QRectF touchRect(0, 0, 40, 40); touchRect.moveCenter(localPos); point.setRect(touchRect); + point.setPressure(1); return point; } +bool QWebKitTest::sendTouchEvent(QQuickWebView* window, QEvent::Type type, const QList<QTouchEvent::TouchPoint>& points, ulong timestamp) +{ + ASSERT(window); + + static QTouchDevice* device = 0; + if (!device) { + device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + } + + Qt::TouchPointStates touchPointStates = 0; + foreach (const QTouchEvent::TouchPoint& touchPoint, points) + touchPointStates |= touchPoint.state(); + + QTouchEvent event(type, device, Qt::NoModifier, touchPointStates, points); + event.setTimestamp(timestamp); + event.setAccepted(false); + + window->touchEvent(&event); + + return event.isAccepted(); +} + bool QWebKitTest::touchTap(QObject* item, qreal x, qreal y, int delay) { - if (!qobject_cast<QQuickWebView*>(item)) { - // FIXME: We only support the actual web view for now. - qWarning("Touch event \"DoubleTap\" not accepted by receiving item"); + QQuickWebView* window = qobject_cast<QQuickWebView*>(item); + + if (!window) { + qWarning("Touch event \"TouchBegin\" not accepted by receiving item"); return false; } // FIXME: implement delay using QTest::qWait() or similar. Q_UNUSED(delay); - m_webViewPrivate->pageView->eventHandler()->handleSingleTapEvent(touchPoint(x, y)); + + QList<QTouchEvent::TouchPoint> points; + points.append(touchPoint(x, y)); + + points[0].setState(Qt::TouchPointPressed); + sendTouchEvent(window, QEvent::TouchBegin, points, QDateTime::currentMSecsSinceEpoch()); + + points[0].setState(Qt::TouchPointReleased); + sendTouchEvent(window, QEvent::TouchEnd, points, QDateTime::currentMSecsSinceEpoch()); return true; } bool QWebKitTest::touchDoubleTap(QObject* item, qreal x, qreal y, int delay) { - if (!qobject_cast<QQuickWebView*>(item)) { - // FIXME: We only support the actual web view for now. - qWarning("Touch event \"DoubleTap\" not accepted by receiving item"); + if (!touchTap(item, x, y, delay)) return false; - } - - // FIXME: implement delay using QTest::qWait() or similar. - Q_UNUSED(delay); - m_webViewPrivate->pageView->eventHandler()->handleDoubleTapEvent(touchPoint(x, y)); + if (!touchTap(item, x, y, delay)) + return false; return true; } @@ -89,44 +120,49 @@ QSize QWebKitTest::contentsSize() const QVariant QWebKitTest::contentsScale() const { - if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine()) - return interactionEngine->currentCSSScale(); - - return m_webViewPrivate->attributes.initialScale; + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return viewport->currentCSSScale(); + return QVariant(); } QVariant QWebKitTest::devicePixelRatio() const { - return m_webViewPrivate->attributes.devicePixelRatio; + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return viewport->m_devicePixelRatio; + return QVariant(); } QVariant QWebKitTest::initialScale() const { - return m_webViewPrivate->attributes.initialScale; + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return viewport->m_rawAttributes.initialScale; + return QVariant(); } QVariant QWebKitTest::minimumScale() const { - if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine()) - return interactionEngine->m_minimumScale; - - return m_webViewPrivate->attributes.minimumScale; + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return viewport->m_minimumScale; + return QVariant(); } QVariant QWebKitTest::maximumScale() const { - if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine()) - return interactionEngine->m_maximumScale; - - return m_webViewPrivate->attributes.maximumScale; + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return viewport->m_maximumScale; + return QVariant(); } QVariant QWebKitTest::isScalable() const { - return !!m_webViewPrivate->attributes.userScalable; + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return !!viewport->m_rawAttributes.userScalable; + return QVariant(); } QVariant QWebKitTest::layoutSize() const { - return QSizeF(m_webViewPrivate->attributes.layoutSize); + if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + return QSizeF(viewport->m_rawAttributes.layoutSize); + return QVariant(); } diff --git a/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h index 613486409..982398d3a 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h @@ -22,6 +22,7 @@ #define qwebkittest_p_h #include "qwebkitglobal.h" +#include "qquickwebview_p.h" #include <QtCore/QObject> #include <QtCore/QPointer> @@ -60,6 +61,8 @@ public: QWebKitTest(QQuickWebViewPrivate* webviewPrivate, QObject* parent = 0); virtual ~QWebKitTest(); + bool sendTouchEvent(QQuickWebView* window, QEvent::Type type, const QList<QTouchEvent::TouchPoint>& points, ulong timestamp); + QSize contentsSize() const; QVariant contentsScale() const; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp index 6c0cb4b62..0e3b33cf7 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp @@ -17,6 +17,8 @@ Boston, MA 02110-1301, USA. */ +#include "config.h" + #include <QMetaEnum> #include <QMetaMethod> #include <QMetaObject> @@ -142,7 +144,7 @@ static void gatherAPI(const QString& prefix, const QMetaMethod& method, QStringL { if (method.access() != QMetaMethod::Private) { const char* methodTypeName = !!strlen(method.typeName()) ? method.typeName() : "void"; -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) *output << QString::fromLatin1("%1%2 --> %3").arg(prefix).arg(QString::fromLatin1(method.methodSignature())).arg(QString::fromLatin1(methodTypeName)); #else *output << QString::fromLatin1("%1%2 --> %3").arg(prefix).arg(method.signature()).arg(methodTypeName); diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro index 5cc6f35f5..fd940d43d 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro @@ -16,3 +16,5 @@ DEFINES += IMPORT_DIR=\"\\\"$${ROOT_BUILD_DIR}$${QMAKE_DIR_SEP}imports\\\"\" OTHER_FILES += \ WebView/* \ common/* + +RESOURCES = resources.qrc diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml index 8210040e8..f6ed4b261 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml @@ -20,6 +20,7 @@ TestWebView { TestCase { id: test name: "WebViewLoadFavIcon" + when: windowShown function init() { if (webView.icon != '') { @@ -36,7 +37,6 @@ TestWebView { var url = Qt.resolvedUrl("../common/favicon.html") webView.url = url verify(webView.waitForLoadSucceeded()) - expectFail("", "https://bugs.webkit.org/show_bug.cgi?id=87133") compare(spy.count, 1) compare(favicon.width, 48) compare(favicon.height, 48) @@ -47,7 +47,6 @@ TestWebView { var url = Qt.resolvedUrl("../common/favicon2.html?favicon=load should work with#whitespace!") webView.url = url verify(webView.waitForLoadSucceeded()) - expectFail("", "https://bugs.webkit.org/show_bug.cgi?id=87133") compare(spy.count, 1) compare(favicon.width, 16) compare(favicon.height, 16) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_itemSelector.qml index d3d7786a3..78ea6f94f 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_itemSelector.qml @@ -4,8 +4,6 @@ import QtWebKit 3.0 import QtWebKit.experimental 1.0 import "../common" -// FIXME: Moved to Desktop tests because we want to have mouseClick() to open the <select> tag. We can move it back -// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083. TestWebView { id: webView @@ -59,7 +57,7 @@ TestWebView { } function openItemSelector() { - mouseClick(webView, 15, 15, Qt.LeftButton) + webView.experimental.test.touchTap(webView, 15, 15) } function test_accept() { diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_messaging.qml index 1b3ab6314..9f16bb8b6 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_messaging.qml @@ -45,7 +45,7 @@ Item { } TestCase { - name: "DesktopWebViewMessaging" + name: "WebViewMessaging" property url testUrl: Qt.resolvedUrl("../common/messaging.html") function init() { diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_multiFileUpload.qml index f43f65672..73ea70845 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_multiFileUpload.qml @@ -4,8 +4,6 @@ import QtWebKit 3.0 import QtWebKit.experimental 1.0 import "../common" -// FIXME: Added to Desktop tests because we want to have mouseClick() to open the <input> tag. We can move it back -// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083. TestWebView { id: webView @@ -46,7 +44,7 @@ TestWebView { } function openItemSelector() { - mouseClick(webView, 15, 15, Qt.LeftButton) + webView.experimental.test.touchTap(webView, 15, 15) } function test_accept() { diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_singleFileUpload.qml index 7ca9efa38..be1409b7f 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_singleFileUpload.qml @@ -4,8 +4,6 @@ import QtWebKit 3.0 import QtWebKit.experimental 1.0 import "../common" -// FIXME: Added to Desktop tests because we want to have mouseClick() to open the <input> tag. We can move it back -// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083. TestWebView { id: webView @@ -51,7 +49,7 @@ TestWebView { } function openItemSelector() { - mouseClick(webView, 15, 15, Qt.LeftButton) + webView.experimental.test.touchTap(webView, 15, 15) } function test_accept() { diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_userScripts.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_userScripts.qml new file mode 100644 index 000000000..3d15aca05 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_userScripts.qml @@ -0,0 +1,113 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import "../common" + +Item { + TestWebView { + id: webView + width: 400 + height: 300 + } + + TestWebView { + id: webViewWithConditionalUserScripts + width: 400 + height: 300 + + onNavigationRequested: { + var urlString = request.url.toString(); + if (urlString.indexOf("test1.html") !== -1) + experimental.userScripts = [Qt.resolvedUrl("../common/change-document-title.js")]; + else if (urlString.indexOf("test2.html") !== -1) + experimental.userScripts = [Qt.resolvedUrl("../common/append-document-title.js")]; + else + experimental.userScripts = []; + } + } + + TestCase { + name: "WebViewUserScripts" + + function init() { + webView.url = ""; + webView.experimental.userScripts = []; + } + + function test_oneScript() { + webView.url = Qt.resolvedUrl("../common/test1.html"); + webView.waitForLoadSucceeded(); + compare(webView.title, "Test page 1"); + + webView.experimental.userScripts = [Qt.resolvedUrl("../common/change-document-title.js")]; + compare(webView.title, "Test page 1"); + + webView.reload(); + webView.waitForLoadSucceeded(); + compare(webView.title, "New title"); + + webView.url = Qt.resolvedUrl("../common/test2.html"); + webView.waitForLoadSucceeded(); + compare(webView.title, "New title"); + + webView.experimental.userScripts = []; + compare(webView.title, "New title"); + + webView.reload(); + webView.waitForLoadSucceeded(); + compare(webView.title, "Test page with huge link area"); + } + + function test_twoScripts() { + webView.url = Qt.resolvedUrl("../common/test1.html"); + webView.waitForLoadSucceeded(); + compare(webView.title, "Test page 1"); + + webView.experimental.userScripts = [Qt.resolvedUrl("../common/change-document-title.js"), Qt.resolvedUrl("../common/append-document-title.js")]; + webView.reload(); + webView.waitForLoadSucceeded(); + compare(webView.title, "New title with appendix"); + + // Make sure we can remove scripts from the preload list. + webView.experimental.userScripts = [Qt.resolvedUrl("../common/append-document-title.js")]; + webView.reload(); + webView.waitForLoadSucceeded(); + compare(webView.title, "Test page 1 with appendix"); + + // Make sure the scripts are loaded in order. + webView.experimental.userScripts = [Qt.resolvedUrl("../common/append-document-title.js"), Qt.resolvedUrl("../common/change-document-title.js")]; + webView.reload(); + webView.waitForLoadSucceeded(); + compare(webView.title, "New title"); + } + + function test_setUserScriptsConditionally() { + webViewWithConditionalUserScripts.url = Qt.resolvedUrl("../common/test1.html"); + webViewWithConditionalUserScripts.waitForLoadSucceeded(); + compare(webViewWithConditionalUserScripts.title, "New title"); + + webViewWithConditionalUserScripts.url = Qt.resolvedUrl("../common/test2.html"); + webViewWithConditionalUserScripts.waitForLoadSucceeded(); + compare(webViewWithConditionalUserScripts.title, "Test page with huge link area with appendix"); + + webViewWithConditionalUserScripts.url = Qt.resolvedUrl("../common/test3.html"); + webViewWithConditionalUserScripts.waitForLoadSucceeded(); + compare(webViewWithConditionalUserScripts.title, "Test page 3"); + } + + function test_bigScript() { + webView.experimental.userScripts = [Qt.resolvedUrl("../common/big-user-script.js")]; + webView.url = Qt.resolvedUrl("../common/test1.html"); + webView.waitForLoadSucceeded(); + compare(webView.title, "Big user script changed title"); + } + + function test_fromResourceFile() { + webView.experimental.userScripts = ["qrc:///common/change-document-title.js"]; + webView.url = Qt.resolvedUrl("../common/test1.html"); + webView.waitForLoadSucceeded(); + compare(webView.title, "New title"); + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/append-document-title.js b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/append-document-title.js new file mode 100644 index 000000000..fb4a2a6f2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/append-document-title.js @@ -0,0 +1 @@ +document.title += " with appendix"; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/big-user-script.js b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/big-user-script.js new file mode 100644 index 000000000..e6e3d2b44 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/big-user-script.js @@ -0,0 +1,110 @@ +// Used to make sure serialization of user scripts between UI process and Web process can handle files bigger +// than the maximum message size defined in ConnectionXXX classes. + +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////// + +document.title = "Big user script changed title"; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/change-document-title.js b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/change-document-title.js new file mode 100644 index 000000000..bdae45c21 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/change-document-title.js @@ -0,0 +1 @@ +document.title = "New title"; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc new file mode 100644 index 000000000..1696aaac1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>common/change-document-title.js</file> + </qresource> +</RCC> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri index 358a2328c..2704efe4a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri +++ b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri @@ -11,6 +11,7 @@ SOURCES += ../util.cpp \ INCLUDEPATH += $$PWD QT += testlib qml quick quick-private webkit +WEBKIT += wtf # For platform macros DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD\\\" \ QWP_PATH=\\\"$${ROOT_BUILD_DIR}/bin\\\" diff --git a/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm b/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm index 70dccc58a..bfc270c69 100644 --- a/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm +++ b/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm @@ -88,7 +88,7 @@ void DynamicLinkerEnvironmentExtractor::processEnvironmentVariable(const char* e return; CString value(equalsLocation + 1); - m_extractedVariables.append(make_pair(name.latin1(), value)); + m_extractedVariables.append(std::make_pair(name.latin1(), value)); } size_t DynamicLinkerEnvironmentExtractor::processLoadCommand(const void* data, size_t length, bool shouldByteSwap) diff --git a/Source/WebKit2/UIProcess/WebContext.cpp b/Source/WebKit2/UIProcess/WebContext.cpp index d2f18070e..742aea62c 100644 --- a/Source/WebKit2/UIProcess/WebContext.cpp +++ b/Source/WebKit2/UIProcess/WebContext.cpp @@ -451,7 +451,7 @@ DownloadProxy* WebContext::download(WebPageProxy* initiatingPage, const Resource void WebContext::postMessageToInjectedBundle(const String& messageName, APIObject* messageBody) { if (!m_process || !m_process->canSendMessage()) { - m_pendingMessagesToPostToInjectedBundle.append(make_pair(messageName, messageBody)); + m_pendingMessagesToPostToInjectedBundle.append(std::make_pair(messageName, messageBody)); return; } diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 72d469590..95e6c1339 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -336,6 +336,7 @@ public: void authenticationRequiredRequest(const String& hostname, const String& realm, const String& prefilledUsername, String& username, String& password); void certificateVerificationRequest(const String& hostname, bool& ignoreErrors); void proxyAuthenticationRequiredRequest(const String& hostname, uint16_t port, const String& prefilledUsername, String& username, String& password); + void setUserScripts(const Vector<String>&); #endif // PLATFORM(QT). #if PLATFORM(QT) diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in index 8541cfb7c..de60a7166 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in @@ -232,17 +232,17 @@ messages -> WebPageProxy { # Drag and drop messages #if ENABLE(DRAG_SUPPORT) DidPerformDragControllerAction(WebCore::DragSession dragSession) -#if PLATFORM(MAC) +#endif +#if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT) SetDragImage(WebCore::IntPoint clientPosition, WebKit::ShareableBitmap::Handle dragImage, bool linkDrag) SetPromisedData(WTF::String pasteboardName, WebKit::SharedMemory::Handle imageHandle, uint64_t imageSize, WTF::String filename, WTF::String extension, WTF::String title, WTF::String url, WTF::String visibleURL, WebKit::SharedMemory::Handle archiveHandle, uint64_t archiveSize) #endif -#if PLATFORM(WIN) +#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT) StartDragDrop(WebCore::IntPoint imagePoint, WebCore::IntPoint dragPoint, uint64_t okEffect, HashMap<UINT,Vector<String> > dataMap, uint64_t fileSize, String pathname, WebKit::SharedMemory::Handle fileContentHandle, WebCore::IntSize dragImageSize, WebKit::SharedMemory::Handle dragImage, bool linkDrag) #endif -#if PLATFORM(QT) || PLATFORM(GTK) +#if (PLATFORM(QT) || PLATFORM(GTK)) && ENABLE(DRAG_SUPPORT) StartDrag(WebCore::DragData dragData, WebKit::ShareableBitmap::Handle dragImage) #endif -#endif #if PLATFORM(MAC) # Dictionary support. diff --git a/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp index fec82b773..ae0fd3669 100644 --- a/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp +++ b/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp @@ -34,7 +34,7 @@ #include <cairo/cairo.h> #if PLATFORM(EFL) -#include "ewk_private.h" +#include "ewk_view_private.h" #endif using namespace WebCore; diff --git a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm index 649176215..68e2cd314 100644 --- a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm +++ b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm @@ -183,6 +183,28 @@ static const NSTimeInterval DefaultWatchdogTimerInterval = 1; #pragma mark - #pragma mark Exposed Interface +static RetainPtr<CGDataProviderRef> createImageProviderWithCopiedData(CGDataProviderRef sourceProvider) +{ + RetainPtr<CFDataRef> data = adoptCF(CGDataProviderCopyData(sourceProvider)); + return adoptCF(CGDataProviderCreateWithCFData(data.get())); +} + +static RetainPtr<CGImageRef> createImageWithCopiedData(CGImageRef sourceImage) +{ + size_t width = CGImageGetWidth(sourceImage); + size_t height = CGImageGetHeight(sourceImage); + size_t bitsPerComponent = CGImageGetBitsPerComponent(sourceImage); + size_t bitsPerPixel = CGImageGetBitsPerPixel(sourceImage); + size_t bytesPerRow = CGImageGetBytesPerRow(sourceImage); + CGColorSpaceRef colorSpace = CGImageGetColorSpace(sourceImage); + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(sourceImage); + RetainPtr<CGDataProviderRef> provider = createImageProviderWithCopiedData(CGImageGetDataProvider(sourceImage)); + bool shouldInterpolate = CGImageGetShouldInterpolate(sourceImage); + CGColorRenderingIntent intent = CGImageGetRenderingIntent(sourceImage); + + return adoptCF(CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, provider.get(), 0, shouldInterpolate, intent)); +} + - (void)enterFullScreen:(NSScreen *)screen { if (_isFullScreen) @@ -204,6 +226,11 @@ static const NSTimeInterval DefaultWatchdogTimerInterval = 1; CGWindowID windowID = [[_webView window] windowNumber]; RetainPtr<CGImageRef> webViewContents(AdoptCF, CGWindowListCreateImage(NSRectToCGRect(webViewFrame), kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageShouldBeOpaque)); + // Using the returned CGImage directly would result in calls to the WindowServer every time + // the image was painted. Instead, copy the image data into our own process to eliminate that + // future overhead. + webViewContents = createImageWithCopiedData(webViewContents.get()); + // Screen updates to be re-enabled in beganEnterFullScreenWithInitialFrame:finalFrame: NSDisableScreenUpdates(); [[self window] setAutodisplay:NO]; diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp index d3d5efef2..45c6499da 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp @@ -24,6 +24,7 @@ #include "qquickwebpage_p.h" #include "qquickwebview_p.h" +#include "qwebkittest_p.h" #include <QPointF> #include <QTransform> #include <QWheelEvent> @@ -113,6 +114,12 @@ inline qreal QtViewportInteractionEngine::itemCoordFromCSS(qreal value) const return value * m_devicePixelRatio; } +static inline QPointF boundPosition(const QPointF minPosition, const QPointF& position, const QPointF& maxPosition) +{ + return QPointF(qBound(minPosition.x(), position.x(), maxPosition.x()), + qBound(minPosition.y(), position.y(), maxPosition.y())); +} + inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect) const { QRectF itemRect; @@ -125,9 +132,9 @@ inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect return itemRect; } -QtViewportInteractionEngine::QtViewportInteractionEngine(QQuickWebView* viewport, QQuickWebPage* content) - : m_viewport(viewport) - , m_content(content) +QtViewportInteractionEngine::QtViewportInteractionEngine(QQuickWebView* viewportItem, QQuickWebPage* pageItem) + : m_viewportItem(viewportItem) + , m_pageItem(pageItem) , m_suspendCount(0) , m_hasSuspendedContent(false) , m_hadUserInteraction(false) @@ -137,10 +144,10 @@ QtViewportInteractionEngine::QtViewportInteractionEngine(QQuickWebView* viewport { reset(); - connect(m_content, SIGNAL(widthChanged()), SLOT(itemSizeChanged()), Qt::DirectConnection); - connect(m_content, SIGNAL(heightChanged()), SLOT(itemSizeChanged()), Qt::DirectConnection); - connect(m_viewport, SIGNAL(movementStarted()), SLOT(flickableMoveStarted()), Qt::DirectConnection); - connect(m_viewport, SIGNAL(movementEnded()), SLOT(flickableMoveEnded()), Qt::DirectConnection); + connect(m_pageItem, SIGNAL(widthChanged()), SLOT(pageItemSizeChanged()), Qt::DirectConnection); + connect(m_pageItem, SIGNAL(heightChanged()), SLOT(pageItemSizeChanged()), Qt::DirectConnection); + connect(m_viewportItem, SIGNAL(movementStarted()), SLOT(flickMoveStarted()), Qt::DirectConnection); + connect(m_viewportItem, SIGNAL(movementEnded()), SLOT(flickMoveEnded()), Qt::DirectConnection); connect(m_scaleAnimation, SIGNAL(valueChanged(QVariant)), SLOT(scaleAnimationValueChanged(QVariant)), Qt::DirectConnection); @@ -168,20 +175,74 @@ qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale) const return innerBoundedCSSScale(cssScale); } -void QtViewportInteractionEngine::setItemRectVisible(const QRectF& itemRect) +void QtViewportInteractionEngine::viewportAttributesChanged(const WebCore::ViewportAttributes& newAttributes) { + m_rawAttributes = newAttributes; + WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes); + + // FIXME: Resetting here can reset more than needed. For instance it will end deferrers. + // This needs to be revised at some point. + reset(); + + + // FIXME: Should get directly from the webPageProxy. + setDevicePixelRatio(m_rawAttributes.devicePixelRatio); + + setAllowsUserScaling(!!m_rawAttributes.userScalable); + setCSSScaleBounds(m_rawAttributes.minimumScale, m_rawAttributes.maximumScale); + + if (!m_hadUserInteraction && !m_hasSuspendedContent) { + // Emits contentsScaleChanged(); + setCSSScale(m_rawAttributes.initialScale); + } + + emit m_viewportItem->experimental()->test()->viewportChanged(); + + // If the web app successively changes the viewport on purpose + // it wants to be in control and we should disable animations. + ViewportUpdateDeferrer guard(this); + setPageItemRectVisible(nearestValidBounds()); +} + +void QtViewportInteractionEngine::pageContentsSizeChanged(const QSize& newSize, const QSize& viewportSize) +{ + float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, viewportSize, newSize); + + if (!qFuzzyCompare(minimumScale, m_rawAttributes.minimumScale)) { + setCSSScaleBounds(minimumScale, m_rawAttributes.maximumScale); + emit m_viewportItem->experimental()->test()->viewportChanged(); + + if (!m_hadUserInteraction && !m_hasSuspendedContent) { + // Emits contentsScaleChanged(); + setCSSScale(minimumScale); + } + } + + // Emit for testing purposes, so that it can be verified that + // we didn't do scale adjustment. + emit m_viewportItem->experimental()->test()->contentsScaleCommitted(); + + ViewportUpdateDeferrer guard(this); + setPageItemRectVisible(nearestValidBounds()); +} + +void QtViewportInteractionEngine::setPageItemRectVisible(const QRectF& itemRect) +{ + ASSERT_WITH_MESSAGE(m_suspendCount, + "setPageItemRectVisible has to be guarded using a ViewportUpdateDeferrer."); + if (itemRect.isEmpty()) return; - qreal itemScale = m_viewport->width() / itemRect.width(); + qreal itemScale = m_viewportItem->width() / itemRect.width(); - m_content->setContentsScale(itemScale); + m_pageItem->setContentsScale(itemScale); // To animate the position together with the scale we multiply the position with the current scale // and add it to the page position (displacement on the flickable contentItem because of additional items). - QPointF newPosition(m_content->pos() + (itemRect.topLeft() * itemScale)); + QPointF newPosition(m_pageItem->pos() + (itemRect.topLeft() * itemScale)); - m_viewport->setContentPos(newPosition); + m_viewportItem->setContentPos(newPosition); } // Ease out overshoot of 1.25 combined with ease in correction of 0.25. Both quadratic to have physical motion. @@ -190,7 +251,7 @@ static qreal physicalOvershoot(qreal t) return (-t * (t - 2)) * 1.25 - (t * t) * 0.25; } -void QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect) +void QtViewportInteractionEngine::animatePageItemRectVisible(const QRectF& itemRect) { ASSERT(m_scaleAnimation->state() == QAbstractAnimation::Stopped); @@ -198,64 +259,74 @@ void QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect) if (scrollAnimationActive()) return; - QRectF currentItemRectVisible = m_viewport->mapRectToWebContent(m_viewport->boundingRect()); - if (itemRect == currentItemRectVisible) + QRectF currentPageItemRectVisible = m_viewportItem->mapRectToWebContent(m_viewportItem->boundingRect()); + if (itemRect == currentPageItemRectVisible) return; - // FIXME: Investigate why that animation doesn't run when we are unfocused. - if (!m_viewport->isVisible() || !m_viewport->hasFocus()) { - // Apply the end result immediately when we are non-visible. - setItemRectVisible(itemRect); - return; - } - QEasingCurve easingCurve; easingCurve.setCustomType(physicalOvershoot); m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); m_scaleAnimation->setEasingCurve(easingCurve); - m_scaleAnimation->setStartValue(currentItemRectVisible); + m_scaleAnimation->setStartValue(currentPageItemRectVisible); m_scaleAnimation->setEndValue(itemRect); m_scaleAnimation->start(); } -void QtViewportInteractionEngine::flickableMoveStarted() +void QtViewportInteractionEngine::flickMoveStarted() { - Q_ASSERT(m_viewport->isMoving()); + Q_ASSERT(m_viewportItem->isMoving()); m_scrollUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); - m_lastScrollPosition = m_viewport->contentPos(); - connect(m_viewport, SIGNAL(contentXChanged()), SLOT(flickableMovingPositionUpdate())); - connect(m_viewport, SIGNAL(contentYChanged()), SLOT(flickableMovingPositionUpdate())); + m_lastScrollPosition = m_viewportItem->contentPos(); + connect(m_viewportItem, SIGNAL(contentXChanged()), SLOT(pageItemPositionChanged())); + connect(m_viewportItem, SIGNAL(contentYChanged()), SLOT(pageItemPositionChanged())); } -void QtViewportInteractionEngine::flickableMoveEnded() +void QtViewportInteractionEngine::flickMoveEnded() { - Q_ASSERT(!m_viewport->isMoving()); + Q_ASSERT(!m_viewportItem->isMoving()); // This method is called on the end of the pan or pan kinetic animation. m_scrollUpdateDeferrer.clear(); m_lastScrollPosition = QPointF(); - disconnect(m_viewport, SIGNAL(contentXChanged()), this, SLOT(flickableMovingPositionUpdate())); - disconnect(m_viewport, SIGNAL(contentYChanged()), this, SLOT(flickableMovingPositionUpdate())); + disconnect(m_viewportItem, SIGNAL(contentXChanged()), this, SLOT(pageItemPositionChanged())); + disconnect(m_viewportItem, SIGNAL(contentYChanged()), this, SLOT(pageItemPositionChanged())); } -void QtViewportInteractionEngine::flickableMovingPositionUpdate() +void QtViewportInteractionEngine::pageItemPositionChanged() { - QPointF newPosition = m_viewport->contentPos(); + QPointF newPosition = m_viewportItem->contentPos(); emit informVisibleContentChange(m_lastScrollPosition - newPosition); m_lastScrollPosition = newPosition; } +void QtViewportInteractionEngine::pageContentPositionRequest(const QPoint& cssPosition) +{ + // Ignore the request if suspended. Can only happen due to delay in event delivery. + if (m_suspendCount) + return; + + qreal endItemScale = m_pageItem->contentsScale(); // Stay at same scale. + + QRectF endPosRange = computePosRangeForPageItemAtScale(endItemScale); + QPointF endPosition = boundPosition(endPosRange.topLeft(), cssPosition * endItemScale, endPosRange.bottomRight()); + + QRectF endVisibleContentRect(endPosition / endItemScale, m_viewportItem->boundingRect().size() / endItemScale); + + ViewportUpdateDeferrer guard(this); + setPageItemRectVisible(endVisibleContentRect); +} + void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/) { switch (newState) { case QAbstractAnimation::Running: - m_viewport->cancelFlick(); + m_viewportItem->cancelFlick(); ASSERT(!m_animationUpdateDeferrer); m_animationUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); break; @@ -267,29 +338,9 @@ void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation: } } -static inline QPointF boundPosition(const QPointF minPosition, const QPointF& position, const QPointF& maxPosition) -{ - return QPointF(qBound(minPosition.x(), position.x(), maxPosition.x()), - qBound(minPosition.y(), position.y(), maxPosition.y())); -} - -void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition) +void QtViewportInteractionEngine::scaleAnimationValueChanged(QVariant value) { - // Ignore the request if suspended. Can only happen due to delay in event delivery. - if (m_suspendCount) - return; - - qreal endItemScale = m_content->contentsScale(); // Stay at same scale. - - QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); - QPointF endPosition = boundPosition(endPosRange.topLeft(), pagePosition * endItemScale, endPosRange.bottomRight()); - - QRectF endVisibleContentRect(endPosition / endItemScale, m_viewport->boundingRect().size() / endItemScale); - - setItemRectVisible(endVisibleContentRect); - - // Make sure that tiles all around the viewport will be requested. - emit informVisibleContentChange(QPointF()); + setPageItemRectVisible(value.toRectF()); } void QtViewportInteractionEngine::touchBegin() @@ -306,10 +357,10 @@ void QtViewportInteractionEngine::touchEnd() m_touchUpdateDeferrer.clear(); } -QRectF QtViewportInteractionEngine::computePosRangeForItemAtScale(qreal itemScale) const +QRectF QtViewportInteractionEngine::computePosRangeForPageItemAtScale(qreal itemScale) const { - const QSizeF contentItemSize = m_content->contentsSize() * itemScale; - const QSizeF viewportItemSize = m_viewport->boundingRect().size(); + const QSizeF contentItemSize = m_pageItem->contentsSize() * itemScale; + const QSizeF viewportItemSize = m_viewportItem->boundingRect().size(); const qreal horizontalRange = contentItemSize.width() - viewportItemSize.width(); const qreal verticalRange = contentItemSize.height() - viewportItemSize.height(); @@ -325,7 +376,7 @@ void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, con QRectF endArea = itemRectFromCSS(targetArea); qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(2.0)); - const QRectF viewportRect = m_viewport->boundingRect(); + const QRectF viewportRect = m_viewportItem->boundingRect(); qreal x; const qreal borderOffset = 10; @@ -345,13 +396,13 @@ void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, con const QPointF viewportHotspot = QPointF(x, /* FIXME: visibleCenter */ viewportRect.center().y()); QPointF endPosition = hotspot * endItemScale - viewportHotspot; - QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); + QRectF endPosRange = computePosRangeForPageItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale); - animateItemRectVisible(endVisibleContentRect); + animatePageItemRectVisible(endVisibleContentRect); } void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea) @@ -368,12 +419,12 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi const int margin = 10; // We want at least a little bit of margin. QRectF endArea = itemRectFromCSS(targetArea.adjusted(-margin, -margin, margin, margin)); - const QRectF viewportRect = m_viewport->boundingRect(); + const QRectF viewportRect = m_viewportItem->boundingRect(); qreal targetCSSScale = viewportRect.size().width() / endArea.size().width(); qreal endCSSScale = innerBoundedCSSScale(qMin(targetCSSScale, qreal(2.5))); qreal endItemScale = itemScaleFromCSS(endCSSScale); - qreal currentScale = m_content->contentsScale(); + qreal currentScale = m_pageItem->contentsScale(); // We want to end up with the target area filling the whole width of the viewport (if possible), // and centralized vertically where the user requested zoom. Thus our hotspot is the center of @@ -383,7 +434,7 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi QPointF endPosition = hotspot * endCSSScale - viewportHotspot; - QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); + QRectF endPosRange = computePosRangeForPageItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale); @@ -396,7 +447,7 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi // Use fuzzy compare with a fixed error to be able to deal with largish differences due to pixel rounding. if (fuzzyCompare(endItemScale, currentScale, 0.01)) { // If moving the viewport would expose more of the targetRect and move at least 40 pixels, update position but do not scale out. - QRectF currentContentRect(m_viewport->contentPos() / currentScale, viewportRect.size() / currentScale); + QRectF currentContentRect(m_viewportItem->contentPos() / currentScale, viewportRect.size() / currentScale); QRectF targetIntersection = endVisibleContentRect.intersected(targetArea); if (!currentContentRect.contains(targetIntersection) && (qAbs(endVisibleContentRect.top() - currentContentRect.top()) >= 40 || qAbs(endVisibleContentRect.left() - currentContentRect.left()) >= 40)) zoomAction = NoZoom; @@ -410,7 +461,7 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi switch (zoomAction) { case ZoomIn: - m_scaleStack.append(ScaleStackItem(currentScale, m_viewport->contentPos().x())); + m_scaleStack.append(ScaleStackItem(currentScale, m_viewportItem->contentPos().x())); m_zoomOutScale = endItemScale; break; case ZoomBack: { @@ -420,7 +471,7 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi // Recalculate endPosition and bound it according to new scale. endPosition.setY(hotspot.y() * endCSSScale - viewportHotspot.y()); endPosition.setX(lastScale.xPosition); - endPosRange = computePosRangeForItemAtScale(endItemScale); + endPosRange = computePosRangeForPageItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); endVisibleContentRect = QRectF(endPosition / endItemScale, viewportRect.size() / endItemScale); break; @@ -435,19 +486,19 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi break; } - animateItemRectVisible(endVisibleContentRect); + animatePageItemRectVisible(endVisibleContentRect); } QRectF QtViewportInteractionEngine::nearestValidBounds() const { qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(currentCSSScale())); - const QRectF viewportRect = m_viewport->boundingRect(); + const QRectF viewportRect = m_viewportItem->boundingRect(); QPointF viewportHotspot = viewportRect.center(); - QPointF endPosition = m_viewport->mapToWebContent(viewportHotspot) * endItemScale - viewportHotspot; + QPointF endPosition = m_viewportItem->mapToWebContent(viewportHotspot) * endItemScale - viewportHotspot; - QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); + QRectF endPosRange = computePosRangeForPageItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale); @@ -468,7 +519,7 @@ void QtViewportInteractionEngine::reset() m_pinchStartScale = -1; m_zoomOutScale = 0.0; - m_viewport->cancelFlick(); + m_viewportItem->cancelFlick(); m_scaleAnimation->stop(); m_scaleUpdateDeferrer.clear(); m_scrollUpdateDeferrer.clear(); @@ -486,22 +537,22 @@ void QtViewportInteractionEngine::setCSSScale(qreal scale) ViewportUpdateDeferrer guard(this); qreal newScale = innerBoundedCSSScale(scale); - m_content->setContentsScale(itemScaleFromCSS(newScale)); + m_pageItem->setContentsScale(itemScaleFromCSS(newScale)); } qreal QtViewportInteractionEngine::currentCSSScale() const { - return cssScaleFromItem(m_content->contentsScale()); + return cssScaleFromItem(m_pageItem->contentsScale()); } bool QtViewportInteractionEngine::scrollAnimationActive() const { - return m_viewport->isFlicking(); + return m_viewportItem->isFlicking(); } bool QtViewportInteractionEngine::panGestureActive() const { - return m_viewport->isDragging(); + return m_viewportItem->isDragging(); } void QtViewportInteractionEngine::panGestureStarted(const QPointF& position, qint64 eventTimestampMillis) @@ -509,19 +560,19 @@ void QtViewportInteractionEngine::panGestureStarted(const QPointF& position, qin // This can only happen as a result of a user interaction. ASSERT(m_hadUserInteraction); - m_viewport->handleFlickableMousePress(position, eventTimestampMillis); + m_viewportItem->handleFlickableMousePress(position, eventTimestampMillis); m_lastPinchCenterInViewportCoordinates = position; } void QtViewportInteractionEngine::panGestureRequestUpdate(const QPointF& position, qint64 eventTimestampMillis) { - m_viewport->handleFlickableMouseMove(position, eventTimestampMillis); + m_viewportItem->handleFlickableMouseMove(position, eventTimestampMillis); m_lastPinchCenterInViewportCoordinates = position; } void QtViewportInteractionEngine::panGestureEnded(const QPointF& position, qint64 eventTimestampMillis) { - m_viewport->handleFlickableMouseRelease(position, eventTimestampMillis); + m_viewportItem->handleFlickableMouseRelease(position, eventTimestampMillis); m_lastPinchCenterInViewportCoordinates = position; } @@ -534,7 +585,7 @@ void QtViewportInteractionEngine::panGestureCancelled() // back inside valid bounds. // When the pinch gesture ends, the content is positioned and scaled // back to valid boundaries. - m_viewport->cancelFlick(); + m_viewportItem->cancelFlick(); } bool QtViewportInteractionEngine::scaleAnimationActive() const @@ -552,8 +603,9 @@ void QtViewportInteractionEngine::cancelScrollAnimation() // pan gesture, the animation is stopped and the content is // immediately positioned back to valid boundaries. - m_viewport->cancelFlick(); - setItemRectVisible(nearestValidBounds()); + m_viewportItem->cancelFlick(); + ViewportUpdateDeferrer guard(this); + setPageItemRectVisible(nearestValidBounds()); } void QtViewportInteractionEngine::interruptScaleAnimation() @@ -581,10 +633,7 @@ void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenter m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; - m_pinchStartScale = m_content->contentsScale(); - - // Reset the tiling look-ahead vector so that tiles all around the viewport will be requested on pinch-end. - emit informVisibleContentChange(QPointF()); + m_pinchStartScale = m_pageItem->contentsScale(); } void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor) @@ -601,12 +650,12 @@ void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinch // Allow zooming out beyond mimimum scale on pages that do not explicitly disallow it. const qreal targetCSSScale = outerBoundedCSSScale(cssScale); - scaleContent(m_viewport->mapToWebContent(pinchCenterInViewportCoordinates), targetCSSScale); + scaleContent(m_viewportItem->mapToWebContent(pinchCenterInViewportCoordinates), targetCSSScale); const QPointF positionDiff = pinchCenterInViewportCoordinates - m_lastPinchCenterInViewportCoordinates; m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; - m_viewport->setContentPos(m_viewport->contentPos() - positionDiff); + m_viewportItem->setContentPos(m_viewportItem->contentPos() - positionDiff); } void QtViewportInteractionEngine::pinchGestureEnded() @@ -618,7 +667,7 @@ void QtViewportInteractionEngine::pinchGestureEnded() m_pinchStartScale = -1; - animateItemRectVisible(nearestValidBounds()); + animatePageItemRectVisible(nearestValidBounds()); m_scaleUpdateDeferrer.clear(); // Clear after starting potential animation, which takes over deferring. } @@ -634,21 +683,22 @@ void QtViewportInteractionEngine::pinchGestureCancelled() * * FIXME: This is currently called twice if you concurrently change width and height. */ -void QtViewportInteractionEngine::itemSizeChanged() +void QtViewportInteractionEngine::pageItemSizeChanged() { if (m_suspendCount) return; - setItemRectVisible(nearestValidBounds()); + ViewportUpdateDeferrer guard(this); + setPageItemRectVisible(nearestValidBounds()); } void QtViewportInteractionEngine::scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale) { - QPointF oldPinchCenterOnViewport = m_viewport->mapFromWebContent(centerInCSSCoordinates); - m_content->setContentsScale(itemScaleFromCSS(cssScale)); - QPointF newPinchCenterOnViewport = m_viewport->mapFromWebContent(centerInCSSCoordinates); + QPointF oldPinchCenterOnViewport = m_viewportItem->mapFromWebContent(centerInCSSCoordinates); + m_pageItem->setContentsScale(itemScaleFromCSS(cssScale)); + QPointF newPinchCenterOnViewport = m_viewportItem->mapFromWebContent(centerInCSSCoordinates); - m_viewport->setContentPos(m_viewport->contentPos() + (newPinchCenterOnViewport - oldPinchCenterOnViewport)); + m_viewportItem->setContentPos(m_viewportItem->contentPos() + (newPinchCenterOnViewport - oldPinchCenterOnViewport)); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h index ba540d548..b7595e569 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h @@ -26,6 +26,7 @@ #include <QtCore/QRectF> #include <QtCore/QVariant> #include <QtCore/QVariantAnimation> +#include <WebCore/ViewportArguments.h> #include <wtf/OwnPtr.h> QT_BEGIN_NAMESPACE @@ -58,14 +59,15 @@ public: qreal currentCSSScale() const; void setAllowsUserScaling(bool allow) { m_allowsUserScaling = allow; } - void setContentToDevicePixelRatio(qreal ratio) {m_devicePixelRatio = ratio; } + void setDevicePixelRatio(qreal ratio) { m_devicePixelRatio = ratio; } - void setItemRectVisible(const QRectF&); - void animateItemRectVisible(const QRectF&); + void setPageItemRectVisible(const QRectF&); + void animatePageItemRectVisible(const QRectF&); QRectF nearestValidBounds() const; - void pagePositionRequest(const QPoint& pos); + void pageContentPositionRequest(const QPoint& pos); + void touchBegin(); void touchEnd(); @@ -73,11 +75,9 @@ public: void cancelScrollAnimation(); bool panGestureActive() const; - void panGestureStarted(const QPointF& position, qint64 eventTimestampMillis); void panGestureRequestUpdate(const QPointF& position, qint64 eventTimestampMillis); void panGestureEnded(const QPointF& position, qint64 eventTimestampMillis); - void panGestureCancelled(); bool scaleAnimationActive() const; @@ -92,32 +92,32 @@ public: void zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea); void focusEditableArea(const QRectF& caretArea, const QRectF& targetArea); + void viewportAttributesChanged(const WebCore::ViewportAttributes&); + void pageContentsSizeChanged(const QSize& newSize, const QSize& viewportSize); + Q_SIGNALS: void contentSuspendRequested(); void contentResumeRequested(); void informVisibleContentChange(const QPointF& trajectory = QPointF()); - void visibleContentRectAndScaleChanged(); - private Q_SLOTS: // Respond to changes of content that are not driven by us, like the page resizing itself. - void itemSizeChanged(); - - void flickableMovingPositionUpdate(); + void pageItemSizeChanged(); + void pageItemPositionChanged(); void scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State); - void scaleAnimationValueChanged(QVariant value) { setItemRectVisible(value.toRectF()); } + void scaleAnimationValueChanged(QVariant value); - void flickableMoveStarted(); // Called when panning starts. - void flickableMoveEnded(); // Called when panning (+ kinetic animation) ends. + void flickMoveStarted(); // Called when panning starts. + void flickMoveEnded(); // Called when panning (+ kinetic animation) ends. private: friend class ViewportUpdateDeferrer; friend class ::QWebKitTest; - QQuickWebView* const m_viewport; - QQuickWebPage* const m_content; + QQuickWebView* const m_viewportItem; + QQuickWebPage* const m_pageItem; qreal cssScaleFromItem(qreal) const; qreal itemScaleFromCSS(qreal) const; @@ -127,6 +127,11 @@ private: qreal innerBoundedCSSScale(qreal) const; qreal outerBoundedCSSScale(qreal) const; + QRectF computePosRangeForPageItemAtScale(qreal itemScale) const; + void scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale); + + WebCore::ViewportAttributes m_rawAttributes; + bool m_allowsUserScaling; qreal m_minimumScale; qreal m_maximumScale; @@ -134,12 +139,9 @@ private: QSize m_layoutSize; - QRectF computePosRangeForItemAtScale(qreal itemScale) const; - - void scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale); - int m_suspendCount; bool m_hasSuspendedContent; + OwnPtr<ViewportUpdateDeferrer> m_scaleUpdateDeferrer; OwnPtr<ViewportUpdateDeferrer> m_scrollUpdateDeferrer; OwnPtr<ViewportUpdateDeferrer> m_touchUpdateDeferrer; diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp index c769c8b03..5132c7939 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp @@ -62,13 +62,29 @@ QtWebIconDatabaseClient::~QtWebIconDatabaseClient() WKIconDatabaseSetIconDatabaseClient(toAPI(m_iconDatabase.get()), 0); } -void QtWebIconDatabaseClient::didChangeIconForPageURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL, const void* clientInfo) +void QtWebIconDatabaseClient::didChangeIconForPageURL(WKIconDatabaseRef, WKURLRef pageURL, const void* clientInfo) { - QUrl qUrl = WKURLCopyQUrl(pageURL); - toQtWebIconDatabaseClient(clientInfo)->requestIconForPageURL(qUrl); + emit toQtWebIconDatabaseClient(clientInfo)->iconChangedForPageURL(toImpl(pageURL)->string()); } -QImage QtWebIconDatabaseClient::iconImageForPageURL(const String& pageURL, const QSize& iconSize) +WTF::String QtWebIconDatabaseClient::iconForPageURL(const WTF::String& pageURL) +{ + String iconURL; + m_iconDatabase->synchronousIconURLForPageURL(pageURL, iconURL); + + if (iconURL.isEmpty()) + return String(); + + // Verify that the image data is actually available before reporting back + // a url, since clients assume that the url can be used directly. + WebCore::Image* iconImage = m_iconDatabase->imageForPageURL(pageURL); + if (!iconImage || iconImage->isNull()) + return String(); + + return iconURL; +} + +QImage QtWebIconDatabaseClient::iconImageForPageURL(const WTF::String& pageURL, const QSize& iconSize) { MutexLocker locker(m_imageLock); @@ -84,33 +100,6 @@ QImage QtWebIconDatabaseClient::iconImageForPageURL(const String& pageURL, const return nativeImage->toImage(); } -unsigned QtWebIconDatabaseClient::iconURLHashForPageURL(const String& pageURL) -{ - String iconURL; - m_iconDatabase->synchronousIconURLForPageURL(pageURL, iconURL); - return StringHash::hash(iconURL); -} - -void QtWebIconDatabaseClient::requestIconForPageURL(const QUrl& pageURL) -{ - String pageURLString = WebCore::KURL(pageURL).string(); - if (iconImageForPageURL(pageURLString).isNull()) - return; - - unsigned iconID = iconURLHashForPageURL(pageURLString); - QUrl url; - url.setScheme(QStringLiteral("image")); - url.setHost(QStringLiteral("webicon")); - QString path; - path.append(QLatin1Char('/')); - path.append(QString::number(m_contextId)); - path.append(QLatin1Char('/')); - path.append(QString::number(iconID)); - url.setPath(path); - url.setEncodedFragment(pageURL.toEncoded()); - emit iconChangedForPageURL(pageURL, url); -} - void QtWebIconDatabaseClient::retainIconForPageURL(const String& pageURL) { m_iconDatabase->retainIconForPageURL(pageURL); diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h index 933ad9abe..65e86e18c 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h +++ b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h @@ -49,18 +49,16 @@ public: QtWebIconDatabaseClient(QtWebContext*); ~QtWebIconDatabaseClient(); + WTF::String iconForPageURL(const WTF::String& pageURL); QImage iconImageForPageURL(const WTF::String& pageURL, const QSize& iconSize = QSize(32, 32)); + void retainIconForPageURL(const WTF::String&); void releaseIconForPageURL(const WTF::String&); -public Q_SLOTS: - void requestIconForPageURL(const QUrl&); - public: - Q_SIGNAL void iconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL); + Q_SIGNAL void iconChangedForPageURL(const QString& pageURL); private: - unsigned iconURLHashForPageURL(const WTF::String&); static void didChangeIconForPageURL(WKIconDatabaseRef, WKURLRef pageURL, const void* clientInfo); uint64_t m_contextId; RefPtr<WebKit::WebIconDatabase> m_iconDatabase; diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp index c1ebaac14..bbdc3a63b 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp @@ -436,7 +436,10 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, return; if (wasEventHandled || event.type() == WebEvent::TouchCancel) { - resetGestureRecognizers(); + m_panGestureRecognizer.cancel(); + m_pinchGestureRecognizer.cancel(); + if (event.type() != WebEvent::TouchMove) + m_tapGestureRecognizer.cancel(); return; } diff --git a/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp index ae3c4aab6..5cafad59c 100644 --- a/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp +++ b/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp @@ -102,6 +102,11 @@ void WebPageProxy::sendApplicationSchemeReply(const QQuickNetworkReply* reply) } } +void WebPageProxy::setUserScripts(const Vector<String>& scripts) +{ + process()->send(Messages::WebPage::SetUserScripts(scripts), m_pageID); +} + #if PLUGIN_ARCHITECTURE(X11) void WebPageProxy::createPluginContainer(uint64_t& windowID) { |