diff options
Diffstat (limited to 'Source/WebKit2/UIProcess')
129 files changed, 3621 insertions, 475 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h index e47b05ff5..9bc9ea607 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h +++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h @@ -70,6 +70,8 @@ class WebGrammarDetail; class WebHitTestResult; class WebIconDatabase; class WebInspectorProxy; +class WebIntentData; +class WebIntentServiceInfo; class WebKeyValueStorageManagerProxy; class WebMediaCacheManagerProxy; class WebNavigationData; @@ -107,6 +109,8 @@ WK_ADD_API_MAPPING(WKGeolocationPositionRef, WebGeolocationPosition) WK_ADD_API_MAPPING(WKGrammarDetailRef, WebGrammarDetail) WK_ADD_API_MAPPING(WKHitTestResultRef, WebHitTestResult) WK_ADD_API_MAPPING(WKIconDatabaseRef, WebIconDatabase) +WK_ADD_API_MAPPING(WKIntentDataRef, WebIntentData) +WK_ADD_API_MAPPING(WKIntentServiceInfoRef, WebIntentServiceInfo) WK_ADD_API_MAPPING(WKKeyValueStorageManagerRef, WebKeyValueStorageManagerProxy) WK_ADD_API_MAPPING(WKMediaCacheManagerRef, WebMediaCacheManagerProxy) WK_ADD_API_MAPPING(WKNavigationDataRef, WebNavigationData) diff --git a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp index a87b6e35b..5949091bb 100644 --- a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp @@ -66,3 +66,8 @@ WKStringRef WKHitTestResultCopyLinkTitle(WKHitTestResultRef hitTestResultRef) { return toCopiedAPI(toImpl(hitTestResultRef)->linkTitle()); } + +bool WKHitTestResultIsContentEditable(WKHitTestResultRef hitTestResultRef) +{ + return toImpl(hitTestResultRef)->isContentEditable(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h index 0ba23df6c..55fd13768 100644 --- a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h +++ b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h @@ -43,6 +43,8 @@ WK_EXPORT WKURLRef WKHitTestResultCopyAbsoluteMediaURL(WKHitTestResultRef hitTes WK_EXPORT WKStringRef WKHitTestResultCopyLinkLabel(WKHitTestResultRef hitTestResult); WK_EXPORT WKStringRef WKHitTestResultCopyLinkTitle(WKHitTestResultRef hitTestResult); +WK_EXPORT bool WKHitTestResultIsContentEditable(WKHitTestResultRef hitTestResult); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.cpp b/Source/WebKit2/UIProcess/API/C/WKPage.cpp index e5682ca4c..c2a21b5bb 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPage.cpp @@ -357,11 +357,17 @@ void WKPageSetPaginationMode(WKPageRef pageRef, WKPaginationMode paginationMode) case kWKPaginationModeUnpaginated: mode = Page::Pagination::Unpaginated; break; - case kWKPaginationModeHorizontal: - mode = Page::Pagination::HorizontallyPaginated; + case kWKPaginationModeLeftToRight: + mode = Page::Pagination::LeftToRightPaginated; break; - case kWKPaginationModeVertical: - mode = Page::Pagination::VerticallyPaginated; + case kWKPaginationModeRightToLeft: + mode = Page::Pagination::RightToLeftPaginated; + break; + case kWKPaginationModeTopToBottom: + mode = Page::Pagination::TopToBottomPaginated; + break; + case kWKPaginationModeBottomToTop: + mode = Page::Pagination::BottomToTopPaginated; break; default: return; @@ -374,10 +380,14 @@ WKPaginationMode WKPageGetPaginationMode(WKPageRef pageRef) switch (toImpl(pageRef)->paginationMode()) { case Page::Pagination::Unpaginated: return kWKPaginationModeUnpaginated; - case Page::Pagination::HorizontallyPaginated: - return kWKPaginationModeHorizontal; - case Page::Pagination::VerticallyPaginated: - return kWKPaginationModeVertical; + case Page::Pagination::LeftToRightPaginated: + return kWKPaginationModeLeftToRight; + case Page::Pagination::RightToLeftPaginated: + return kWKPaginationModeRightToLeft; + case Page::Pagination::TopToBottomPaginated: + return kWKPaginationModeTopToBottom; + case Page::Pagination::BottomToTopPaginated: + return kWKPaginationModeBottomToTop; } ASSERT_NOT_REACHED(); diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.h b/Source/WebKit2/UIProcess/API/C/WKPage.h index 47c076f8c..035f51daa 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.h +++ b/Source/WebKit2/UIProcess/API/C/WKPage.h @@ -73,6 +73,8 @@ typedef bool (*WKPageShouldGoToBackForwardListItemCallback)(WKPageRef page, WKBa typedef void (*WKPageDidNewFirstVisuallyNonEmptyLayoutCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo); typedef void (*WKPageWillGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, WKTypeRef userData, const void *clientInfo); typedef void (*WKPagePluginDidFailCallback)(WKPageRef page, WKErrorCode errorCode, WKStringRef mimeType, WKStringRef pluginIdentifier, WKStringRef pluginVersion, const void* clientInfo); +typedef void (*WKPageDidReceiveIntentForFrameCallback)(WKPageRef page, WKFrameRef frame, WKIntentDataRef intent, const void *clientInfo); +typedef void (*WKPageRegisterIntentServiceForFrameCallback)(WKPageRef page, WKFrameRef frame, WKIntentServiceInfoRef serviceInfo, const void *clientInfo); // Deprecated typedef void (*WKPageDidFailToInitializePluginCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef mimeType, const void* clientInfo); @@ -120,10 +122,14 @@ struct WKPageLoaderClient { WKPageCallback interactionOccurredWhileProcessUnresponsive; WKPagePluginDidFailCallback pluginDidFail; + + // Version 2 + WKPageDidReceiveIntentForFrameCallback didReceiveIntentForFrame; + WKPageRegisterIntentServiceForFrameCallback registerIntentServiceForFrame; }; typedef struct WKPageLoaderClient WKPageLoaderClient; -enum { kWKPageLoaderClientCurrentVersion = 1 }; +enum { kWKPageLoaderClientCurrentVersion = 2 }; // Policy Client. typedef void (*WKPageDecidePolicyForNavigationActionCallback)(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo); diff --git a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h index 18860fd74..129d3959b 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h @@ -54,8 +54,10 @@ WK_EXPORT WKStringRef WKPageCopyStandardUserAgentWithApplicationName(WKStringRef enum { kWKPaginationModeUnpaginated, - kWKPaginationModeHorizontal, - kWKPaginationModeVertical, + kWKPaginationModeLeftToRight, + kWKPaginationModeRightToLeft, + kWKPaginationModeTopToBottom, + kWKPaginationModeBottomToTop, }; typedef uint32_t WKPaginationMode; diff --git a/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp b/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp index 8cfe143e5..e3024e762 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp @@ -28,7 +28,10 @@ #include "WKAPICast.h" #include "WebPluginSiteDataManager.h" + +#if ENABLE(NETSCAPE_PLUGIN_API) #include <WebCore/npapi.h> +#endif using namespace WebKit; using namespace std; @@ -43,6 +46,7 @@ void WKPluginSiteDataManagerGetSitesWithData(WKPluginSiteDataManagerRef managerR toImpl(managerRef)->getSitesWithData(ArrayCallback::create(context, callback)); } +#if ENABLE(NETSCAPE_PLUGIN_API) static uint64_t toNPClearSiteDataFlags(WKClearSiteDataFlags flags) { if (flags == kWKClearSiteDataFlagsClearAll) @@ -53,13 +57,18 @@ static uint64_t toNPClearSiteDataFlags(WKClearSiteDataFlags flags) result |= NP_CLEAR_CACHE; return result; } +#endif void WKPluginSiteDataManagerClearSiteData(WKPluginSiteDataManagerRef managerRef, WKArrayRef sitesRef, WKClearSiteDataFlags flags, uint64_t maxAgeInSeconds, void* context, WKPluginSiteDataManagerClearSiteDataFunction function) { +#if ENABLE(NETSCAPE_PLUGIN_API) toImpl(managerRef)->clearSiteData(toImpl(sitesRef), toNPClearSiteDataFlags(flags), maxAgeInSeconds, VoidCallback::create(context, function)); +#endif } void WKPluginSiteDataManagerClearAllSiteData(WKPluginSiteDataManagerRef managerRef, void* context, WKPluginSiteDataManagerClearSiteDataFunction function) { +#if ENABLE(NETSCAPE_PLUGIN_API) toImpl(managerRef)->clearSiteData(0, NP_CLEAR_ALL, numeric_limits<uint64_t>::max(), VoidCallback::create(context, function)); +#endif } diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h b/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h index 273eb7cc2..1c9c001f2 100644 --- a/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h +++ b/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h @@ -34,11 +34,13 @@ extern "C" { #endif typedef void (*WKSoupRequestManagerDidReceiveURIRequestCallback)(WKSoupRequestManagerRef soupRequestManagerRef, WKURLRef urlRef, uint64_t requestID, const void* clientInfo); +typedef void (*WKSoupRequestManagerDidFailToLoadURIRequestCallback)(WKSoupRequestManagerRef soupRequestManagerRef, uint64_t requestID, const void* clientInfo); struct WKSoupRequestManagerClient { - int version; - const void* clientInfo; - WKSoupRequestManagerDidReceiveURIRequestCallback didReceiveURIRequest; + int version; + const void* clientInfo; + WKSoupRequestManagerDidReceiveURIRequestCallback didReceiveURIRequest; + WKSoupRequestManagerDidFailToLoadURIRequestCallback didFailToLoadURIRequest; }; typedef struct WKSoupRequestManagerClient WKSoupRequestManagerClient; diff --git a/Source/WebKit2/UIProcess/API/efl/EWebKit2.h b/Source/WebKit2/UIProcess/API/efl/EWebKit2.h new file mode 100644 index 000000000..e143b781b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/efl/EWebKit2.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * @file EWebKit2.h + * @brief Contains the header files that are required by WebKit2-EFL. + * + * It includes the all header files that are exported to public API. + */ + +#ifndef EWebKit2_h +#define EWebKit2_h + +#include "ewk_context.h" +#include "ewk_view.h" + +#endif // EWebKit2_h diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_context.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_context.cpp new file mode 100644 index 000000000..90685cf92 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/efl/ewk_context.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "ewk_context.h" + +#include "WKAPICast.h" +#include "WKRetainPtr.h" +#include "ewk_context_private.h" + +using namespace WebKit; + +struct _Ewk_Context { + WKRetainPtr<WKContextRef> context; + + _Ewk_Context(WKContextRef contextRef) + { + this->context = contextRef; + } +}; + +WKContextRef ewk_context_WKContext_get(const Ewk_Context* ewkContext) +{ + return ewkContext->context.get(); +} + +Ewk_Context* ewk_context_default_get() +{ + DEFINE_STATIC_LOCAL(Ewk_Context, defaultContext, (WKContextGetSharedProcessContext())); + return &defaultContext; +} diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_context.h b/Source/WebKit2/UIProcess/API/efl/ewk_context.h new file mode 100644 index 000000000..794d05204 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/efl/ewk_context.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * @file ewk_context.h + * @brief Describes the context API. + * + * @note ewk_context encapsulates all pages related to specific use of WebKit. + * All pages in this context share the same visited link set, + * local storage set, and preferences. + */ + +#ifndef ewk_context_h +#define ewk_context_h + +#include <Evas.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** Creates a type name for @a _Ewk_Context. */ +typedef struct _Ewk_Context Ewk_Context; + +/** + * Gets default Ewk_Context instance. + * + * @return Ewk_Context object. + */ +EAPI Ewk_Context *ewk_context_default_get(); + +#ifdef __cplusplus +} +#endif + +#endif // ewk_context_h diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_context_private.h b/Source/WebKit2/UIProcess/API/efl/ewk_context_private.h new file mode 100644 index 000000000..813a94257 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/efl/ewk_context_private.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ewk_context_private_h +#define ewk_context_private_h + +#include <WebKit2/WKBase.h> + +typedef struct _Ewk_Context Ewk_Context; + +WKContextRef ewk_context_WKContext_get(const Ewk_Context*); + +#endif // ewk_context_private_h diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp index 269c072d6..01fd5e669 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2011 Samsung Electronics + Copyright (C) 2012 Intel Corporation. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -25,6 +26,13 @@ #include "NativeWebWheelEvent.h" #include "PageClientImpl.h" #include "WKAPICast.h" +#include "WKRetainPtr.h" +#include "WKURL.h" +#include "ewk_context.h" +#include "ewk_context_private.h" +#include "ewk_view_loader_client_private.h" +#include "ewk_view_private.h" +#include <wtf/text/CString.h> using namespace WebKit; using namespace WebCore; @@ -33,6 +41,8 @@ static const char EWK_VIEW_TYPE_STR[] = "EWK2_View"; struct _Ewk_View_Private_Data { OwnPtr<PageClientImpl> pageClient; + const char* uri; + const char* title; }; #define EWK_VIEW_TYPE_CHECK(ewkView, result) \ @@ -259,6 +269,8 @@ static void _ewk_view_priv_del(Ewk_View_Private_Data* priv) return; priv->pageClient = nullptr; + eina_stringshare_del(priv->uri); + eina_stringshare_del(priv->title); free(priv); } @@ -461,7 +473,7 @@ static inline Evas_Smart* _ewk_view_smart_class_new(void) return smart; } -Evas_Object* ewk_view_add(Evas* canvas, WKContextRef contextRef, WKPageGroupRef pageGroupRef) +Evas_Object* ewk_view_base_add(Evas* canvas, WKContextRef contextRef, WKPageGroupRef pageGroupRef) { Evas_Object* ewkView = evas_object_smart_add(canvas, _ewk_view_smart_class_new()); if (!ewkView) @@ -480,16 +492,80 @@ Evas_Object* ewk_view_add(Evas* canvas, WKContextRef contextRef, WKPageGroupRef } priv->pageClient = PageClientImpl::create(toImpl(contextRef), toImpl(pageGroupRef), ewkView); + ewk_view_loader_client_attach(toAPI(priv->pageClient->page()), ewkView); return ewkView; } -WKPageRef ewk_view_page_get(Evas_Object* ewkView) +Evas_Object* ewk_view_add_with_context(Evas* canvas, Ewk_Context* context) +{ + return ewk_view_base_add(canvas, ewk_context_WKContext_get(context), 0); +} + +Evas_Object* ewk_view_add(Evas* canvas) +{ + return ewk_view_add_with_context(canvas, ewk_context_default_get()); +} + +Eina_Bool ewk_view_uri_set(Evas_Object* ewkView, const char* uri) { EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0); EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0); - return toAPI(priv->pageClient->page()); + WKRetainPtr<WKURLRef> url(AdoptWK, WKURLCreateWithUTF8CString(uri)); + WKPageLoadURL(toAPI(priv->pageClient->page()), url.get()); + + eina_stringshare_replace(&priv->uri, uri); + + return true; +} + +const char* ewk_view_uri_get(const Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0); + + return priv->uri; +} + +Eina_Bool ewk_view_reload(Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false); + + WKPageReload(toAPI(priv->pageClient->page())); + return true; +} + +Eina_Bool ewk_view_stop(Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false); + + WKPageStopLoading(toAPI(priv->pageClient->page())); + return true; +} + +const char* ewk_view_title_get(const Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0); + + CString title = priv->pageClient->page()->pageTitle().utf8(); + eina_stringshare_replace(&priv->title, title.data()); + + return priv->title; +} + +/** + * @internal + * The view title was changed by the frame loader. + * + * Emits signal: "title,changed" with pointer to new title string. + */ +void ewk_view_title_changed(Evas_Object* ewkView, const char* title) +{ + evas_object_smart_callback_call(ewkView, "title,changed", const_cast<char*>(title)); } void ewk_view_display(Evas_Object* ewkView, const IntRect& rect) @@ -501,6 +577,48 @@ void ewk_view_display(Evas_Object* ewkView, const IntRect& rect) evas_object_image_data_update_add(smartData->image, rect.x(), rect.y(), rect.width(), rect.height()); } +Eina_Bool ewk_view_back(Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false); + + WKPageRef pageRef = toAPI(priv->pageClient->page()); + if (WKPageCanGoBack(pageRef)) { + WKPageGoBack(pageRef); + return true; + } + return false; +} + +Eina_Bool ewk_view_forward(Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false); + + WKPageRef pageRef = toAPI(priv->pageClient->page()); + if (WKPageCanGoForward(pageRef)) { + WKPageGoForward(pageRef); + return true; + } + return false; +} + +Eina_Bool ewk_view_back_possible(Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false); + + return WKPageCanGoBack(toAPI(priv->pageClient->page())); +} + +Eina_Bool ewk_view_forward_possible(Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false); + + return WKPageCanGoForward(toAPI(priv->pageClient->page())); +} + void ewk_view_image_data_set(Evas_Object* ewkView, void* imageData, const IntSize& size) { EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData); diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.h b/Source/WebKit2/UIProcess/API/efl/ewk_view.h index c8956bca7..cb5b6500a 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.h @@ -1,5 +1,6 @@ /* Copyright (C) 2011 Samsung Electronics + Copyright (C) 2012 Intel Corporation. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -17,11 +18,22 @@ Boston, MA 02110-1301, USA. */ +/** + * @file ewk_view.h + * @brief WebKit main smart object. + * + * This object provides view related APIs of WebKit2 to EFL object. + * + * The following signals (see evas_object_smart_callback_add()) are emitted: + * + * - "title,changed", const char*: title of the main frame was changed. + */ + #ifndef ewk_view_h #define ewk_view_h +#include "ewk_context.h" #include <Evas.h> -#include <WebKit2/WKBase.h> #ifdef __cplusplus extern "C" { @@ -117,24 +129,117 @@ struct _Ewk_View_Smart_Data { }; /** - * Creates a new EFL WebKit View object. + * Creates a new EFL WebKit view object. * * @param e canvas object where to create the view object - * @param context WKContext's Reference pointer - * @param page_group WKPageGroup's Reference pointer * * @return view object on success or @c 0 on failure */ -EAPI Evas_Object* ewk_view_add(Evas* e, WKContextRef context, WKPageGroupRef page_group); +EAPI Evas_Object *ewk_view_add(Evas *e); + +/** + * Creates a new EFL WebKit view object based on specific Ewk_Context. + * + * @param e canvas object where to create the view object + * @param context Ewk_Context object to declare process model + * + * @return view object on success or @c 0 on failure + */ +EAPI Evas_Object *ewk_view_add_with_context(Evas *e, Ewk_Context *context); + +/** + * Asks the object to load the given URI. + * + * @param o view object to load @a URI + * @param uri uniform resource identifier to load + * + * @return @c EINA_TRUE is returned if @a o is valid, irrespective of load. + */ +EAPI Eina_Bool ewk_view_uri_set(Evas_Object *o, const char *uri); + +/** + * Returns the current URI string of view object. + * + * It returns an internal string and should not + * be modified. The string is guaranteed to be stringshared. + * + * @param o view object to get current URI + * + * @return current URI on success or @c 0 on failure + */ +EAPI const char *ewk_view_uri_get(const Evas_Object *o); + +/** + * Asks the main frame to reload the current document. + * + * @param o view object to reload current document + * + * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise + * + * @see ewk_view_reload_full() + */ +EAPI Eina_Bool ewk_view_reload(Evas_Object *o); /** - * Gets the WKPageRef of this view. + * Asks the main frame to stop loading. + * + * @param o view object to stop loading + * + * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ewk_view_stop(Evas_Object *o); + +/* + * Asks the main frame to navigate back in the history. + * + * @param o view object to navigate back + * + * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise + * + * @see ewk_frame_back() + */ +EAPI Eina_Bool ewk_view_back(Evas_Object *o); + +/** + * Asks the main frame to navigate forward in the history. + * + * @param o view object to navigate forward + * + * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise + * + * @see ewk_frame_forward() + */ +EAPI Eina_Bool ewk_view_forward(Evas_Object *o); + +/** + * Queries if it is possible to navigate backwards one item in the history. + * + * @param o view object to query if backward navigation is possible + * + * @return @c EINA_TRUE if it is possible to navigate backwards in the history, @c EINA_FALSE otherwise + */ +EAPI Eina_Bool ewk_view_back_possible(Evas_Object *o); + +/** + * Queries if it is possible to navigate forwards one item in the history. + * + * @param o view object to query if forward navigation is possible + * + * @return @c EINA_TRUE if it is possible to navigate forwards in the history, @c EINA_FALSE otherwise + */ +EAPI Eina_Bool ewk_view_forward_possible(Evas_Object *o); + +/** + * Gets the current title of the main frame. + * + * It returns an internal string and should not + * be modified. The string is guaranteed to be stringshared. * - * @param o the view object to get the WKPageRef + * @param o view object to get current title * - * @return the WKPageRef of this view + * @return current title on success or @c 0 on failure */ -EAPI WKPageRef ewk_view_page_get(Evas_Object* o); +EAPI const char *ewk_view_title_get(const Evas_Object *o); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view_loader_client.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view_loader_client.cpp new file mode 100644 index 000000000..e98e154c6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view_loader_client.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "WKFrame.h" +#include "ewk_view_loader_client_private.h" +#include "ewk_view_private.h" +#include <wtf/text/CString.h> + +using namespace WebKit; + +static void didReceiveTitleForFrame(WKPageRef, WKStringRef title, WKFrameRef frame, WKTypeRef, const void* clientInfo) +{ + if (!WKFrameIsMainFrame(frame)) + return; + + Evas_Object* ewkView = static_cast<Evas_Object*>(const_cast<void*>(clientInfo)); + ewk_view_title_changed(ewkView, toImpl(title)->string().utf8().data()); +} + +void ewk_view_loader_client_attach(WKPageRef pageRef, Evas_Object* ewkView) +{ + WKPageLoaderClient loadClient; + memset(&loadClient, 0, sizeof(WKPageLoaderClient)); + loadClient.version = kWKPageLoaderClientCurrentVersion; + loadClient.clientInfo = ewkView; + loadClient.didReceiveTitleForFrame = didReceiveTitleForFrame; + WKPageSetPageLoaderClient(pageRef, &loadClient); +} diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view_loader_client_private.h b/Source/WebKit2/UIProcess/API/efl/ewk_view_loader_client_private.h new file mode 100644 index 000000000..615c019fc --- /dev/null +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view_loader_client_private.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ewk_view_loader_client_private_h +#define ewk_view_loader_client_private_h + +#include <Evas.h> +#include <WebKit2/WKBase.h> + +void ewk_view_loader_client_attach(WKPageRef pageRef, Evas_Object* ewkView); + +#endif // ewk_view_loader_client_private_h diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view_private.h b/Source/WebKit2/UIProcess/API/efl/ewk_view_private.h index e776725cc..2b3f476ba 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view_private.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view_private.h @@ -21,7 +21,9 @@ #ifndef ewk_view_private_h #define ewk_view_private_h +#include "WebPageProxy.h" #include <Evas.h> +#include <WebKit2/WKBase.h> namespace WebCore { class IntRect; @@ -30,5 +32,8 @@ 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); +void ewk_view_title_changed(Evas_Object* ewkView, const char* title); + +Evas_Object* ewk_view_base_add(Evas* canvas, WKContextRef, WKPageGroupRef); #endif // ewk_view_private_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp new file mode 100644 index 000000000..f9d713180 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitContextMenuClient.h" + +#include "WebKitPrivate.h" +#include "WebKitWebViewBasePrivate.h" +#include "WebKitWebViewPrivate.h" + +using namespace WebKit; + +static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo) +{ + webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), proposedMenu, hitTestResult); +} + +void attachContextMenuClientToView(WebKitWebView* webView) +{ + WKPageContextMenuClient wkContextMenuClient = { + kWKPageContextMenuClientCurrentVersion, + webView, // clientInfo + 0, // getContextMenuFromProposedMenu_deprecatedForUseWithV0 + 0, // customContextMenuItemSelected + 0, // contextMenuDismissed + getContextMenuFromProposedMenu, + }; + WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); + WKPageSetPageContextMenuClient(wkPage, &wkContextMenuClient); +} + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h new file mode 100644 index 000000000..9b28bf998 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitContextMenuClient_h +#define WebKitContextMenuClient_h + +#include "WebKitWebView.h" + +void attachContextMenuClientToView(WebKitWebView*); + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp index 61d316f6c..e0d7a60ea 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp @@ -512,3 +512,19 @@ gdouble webkit_download_get_elapsed_time(WebKitDownload* download) return g_timer_elapsed(priv->timer.get(), 0); } + +/** + * webkit_download_get_received_data_length: + * @download: a #WebKitDownload + * + * Gets the length of the data already downloaded for @download + * in bytes. + * + * Returns: the amount of bytes already downloaded. + */ +guint64 webkit_download_get_received_data_length(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0); + + return download->priv->currentSize; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h index b4a2d3bab..a02aa57fd 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h @@ -56,29 +56,32 @@ struct _WebKitDownloadClass { }; WEBKIT_API GType -webkit_download_get_type (void); +webkit_download_get_type (void); WEBKIT_API WebKitURIRequest * -webkit_download_get_request (WebKitDownload *download); +webkit_download_get_request (WebKitDownload *download); WEBKIT_API const gchar * -webkit_download_get_destination (WebKitDownload *download); +webkit_download_get_destination (WebKitDownload *download); WEBKIT_API void -webkit_download_set_destination (WebKitDownload *download, - const gchar *uri); +webkit_download_set_destination (WebKitDownload *download, + const gchar *uri); WEBKIT_API WebKitURIResponse* -webkit_download_get_response (WebKitDownload *download); +webkit_download_get_response (WebKitDownload *download); WEBKIT_API void -webkit_download_cancel (WebKitDownload *download); +webkit_download_cancel (WebKitDownload *download); WEBKIT_API gdouble -webkit_download_get_estimated_progress (WebKitDownload *download); +webkit_download_get_estimated_progress (WebKitDownload *download); WEBKIT_API gdouble -webkit_download_get_elapsed_time (WebKitDownload *download); +webkit_download_get_elapsed_time (WebKitDownload *download); + +WEBKIT_API guint64 +webkit_download_get_received_data_length (WebKitDownload* download); G_END_DECLS diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp new file mode 100644 index 000000000..51f186842 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitGeolocationPermissionRequest.h" + +#include "WebKitGeolocationPermissionRequestPrivate.h" +#include "WebKitPermissionRequest.h" + +/** + * SECTION: WebKitGeolocationPermissionRequest + * @Short_description: A permission request for sharing user's location + * @Title: WebKitGeolocationPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitGeolocationPermissionRequest represents a request for + * permission to decide whether WebKit should provide the user's + * location to a website when requested throught the Geolocation API. + */ +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); +G_DEFINE_TYPE_WITH_CODE(WebKitGeolocationPermissionRequest, webkit_geolocation_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, + webkit_permission_request_interface_init)) + +struct _WebKitGeolocationPermissionRequestPrivate { + WKRetainPtr<WKGeolocationPermissionRequestRef> wkRequest; + bool madeDecision; +}; + +static void webkitGeolocationPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(request)); + + WebKitGeolocationPermissionRequestPrivate* priv = WEBKIT_GEOLOCATION_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + WKGeolocationPermissionRequestAllow(priv->wkRequest.get()); + priv->madeDecision = true; +} + +static void webkitGeolocationPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(request)); + + WebKitGeolocationPermissionRequestPrivate* priv = WEBKIT_GEOLOCATION_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + WKGeolocationPermissionRequestDeny(priv->wkRequest.get()); + priv->madeDecision = true; +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitGeolocationPermissionRequestAllow; + iface->deny = webkitGeolocationPermissionRequestDeny; +} + +static void webkit_geolocation_permission_request_init(WebKitGeolocationPermissionRequest* request) +{ + request->priv = G_TYPE_INSTANCE_GET_PRIVATE(request, WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST, WebKitGeolocationPermissionRequestPrivate); + new (request->priv) WebKitGeolocationPermissionRequestPrivate(); +} + +static void webkitGeolocationPermissionRequestFinalize(GObject* object) +{ + WebKitGeolocationPermissionRequestPrivate* priv = WEBKIT_GEOLOCATION_PERMISSION_REQUEST(object)->priv; + + // Default behaviour when no decision has been made is denying the request. + if (!priv->madeDecision) + WKGeolocationPermissionRequestDeny(priv->wkRequest.get()); + + priv->~WebKitGeolocationPermissionRequestPrivate(); + G_OBJECT_CLASS(webkit_geolocation_permission_request_parent_class)->finalize(object); +} + +static void webkit_geolocation_permission_request_class_init(WebKitGeolocationPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->finalize = webkitGeolocationPermissionRequestFinalize; + g_type_class_add_private(klass, sizeof(WebKitGeolocationPermissionRequestPrivate)); +} + +WebKitGeolocationPermissionRequest* webkitGeolocationPermissionRequestCreate(WKGeolocationPermissionRequestRef wkRequest) +{ + WebKitGeolocationPermissionRequest* geolocationPermissionRequest = WEBKIT_GEOLOCATION_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST, NULL)); + geolocationPermissionRequest->priv->wkRequest = wkRequest; + return geolocationPermissionRequest; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.h new file mode 100644 index 000000000..033b63f7e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitGeolocationPermissionRequest_h +#define WebKitGeolocationPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST (webkit_geolocation_permission_request_get_type()) +#define WEBKIT_GEOLOCATION_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST, WebKitGeolocationPermissionRequest)) +#define WEBKIT_GEOLOCATION_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST, WebKitGeolocationPermissionRequestClass)) +#define WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST)) +#define WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST)) +#define WEBKIT_GEOLOCATION_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST, WebKitGeolocationPermissionRequestClass)) + +typedef struct _WebKitGeolocationPermissionRequest WebKitGeolocationPermissionRequest; +typedef struct _WebKitGeolocationPermissionRequestClass WebKitGeolocationPermissionRequestClass; +typedef struct _WebKitGeolocationPermissionRequestPrivate WebKitGeolocationPermissionRequestPrivate; + +struct _WebKitGeolocationPermissionRequest { + GObject parent; + + /*< private >*/ + WebKitGeolocationPermissionRequestPrivate *priv; +}; + +struct _WebKitGeolocationPermissionRequestClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_geolocation_permission_request_get_type (void); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequestPrivate.h new file mode 100644 index 000000000..e6de68753 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequestPrivate.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitGeolocationPermissionRequestPrivate_h +#define WebKitGeolocationPermissionRequestPrivate_h + +#include "WebKitGeolocationPermissionRequest.h" +#include "WebKitPrivate.h" + +WebKitGeolocationPermissionRequest* webkitGeolocationPermissionRequestCreate(WKGeolocationPermissionRequestRef); + +#endif // WebKitGeolocationPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp new file mode 100644 index 000000000..648c8093b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebKitGeolocationProvider.h" + +#if ENABLE(GEOLOCATION) + +static inline WebKitGeolocationProvider* toGeolocationProvider(const void* clientInfo) +{ + return static_cast<WebKitGeolocationProvider*>(const_cast<void*>(clientInfo)); +} + +static void startUpdatingCallback(WKGeolocationManagerRef geolocationManager, const void* clientInfo) +{ + toGeolocationProvider(clientInfo)->startUpdating(); +} + +static void stopUpdatingCallback(WKGeolocationManagerRef geolocationManager, const void* clientInfo) +{ + toGeolocationProvider(clientInfo)->stopUpdating(); +} + +WebKitGeolocationProvider::~WebKitGeolocationProvider() +{ + m_provider.stopUpdating(); +} + +PassRefPtr<WebKitGeolocationProvider> WebKitGeolocationProvider::create(WKGeolocationManagerRef wkGeolocationManager) +{ + return adoptRef(new WebKitGeolocationProvider(wkGeolocationManager)); +} + +WebKitGeolocationProvider::WebKitGeolocationProvider(WKGeolocationManagerRef wkGeolocationManager) + : m_wkGeolocationManager(wkGeolocationManager) + , m_provider(this) +{ + ASSERT(wkGeolocationManager); + + WKGeolocationProvider wkGeolocationProvider = { + kWKGeolocationProviderCurrentVersion, + this, // clientInfo + startUpdatingCallback, + stopUpdatingCallback + }; + WKGeolocationManagerSetProvider(m_wkGeolocationManager.get(), &wkGeolocationProvider); +} + +void WebKitGeolocationProvider::startUpdating() +{ + m_provider.startUpdating(); +} + +void WebKitGeolocationProvider::stopUpdating() +{ + m_provider.stopUpdating(); +} + +void WebKitGeolocationProvider::notifyPositionChanged(int timestamp, double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy) +{ + WKRetainPtr<WKGeolocationPositionRef> wkGeolocationPosition(AdoptWK, WKGeolocationPositionCreate(timestamp, latitude, longitude, accuracy)); + WKGeolocationManagerProviderDidChangePosition(m_wkGeolocationManager.get(), wkGeolocationPosition.get()); +} + +void WebKitGeolocationProvider::notifyErrorOccurred(const char* message) +{ + WKGeolocationManagerProviderDidFailToDeterminePosition(m_wkGeolocationManager.get()); +} + +#endif // ENABLE(GEOLOCATION) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h new file mode 100644 index 000000000..a02bfcb08 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitGeolocationProvider_h +#define WebKitGeolocationProvider_h + +#if ENABLE(GEOLOCATION) + +#include "WebKitPrivate.h" +#include <WebCore/GeolocationProviderGeoclue.h> +#include <WebCore/GeolocationProviderGeoclueClient.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +class WebKitGeolocationProvider : public RefCounted<WebKitGeolocationProvider>, public WebCore::GeolocationProviderGeoclueClient { +public: + virtual ~WebKitGeolocationProvider(); + static PassRefPtr<WebKitGeolocationProvider> create(WKGeolocationManagerRef); + + void startUpdating(); + void stopUpdating(); + +private: + WebKitGeolocationProvider(WKGeolocationManagerRef); + + // GeolocationProviderGeoclueClient interface. + virtual void notifyPositionChanged(int, double, double, double, double, double); + virtual void notifyErrorOccurred(const char*); + + WKRetainPtr<WKGeolocationManagerRef> m_wkGeolocationManager; + WebCore::GeolocationProviderGeoclue m_provider; +}; + +#endif // ENABLE(GEOLOCATION) + +#endif // WebKitGeolocationProvider_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp index 928b4dc42..034768cb0 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp @@ -253,6 +253,9 @@ WebKitHitTestResult* webkitHitTestResultCreate(WKHitTestResultRef wkHitTestResul if (!mediaURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA; + if (WKHitTestResultIsContentEditable(wkHitTestResult)) + context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE; + const String& linkTitle = toImpl(wkHitTestResult)->linkTitle(); const String& linkLabel = toImpl(wkHitTestResult)->linkLabel(); @@ -348,6 +351,23 @@ gboolean webkit_hit_test_result_context_is_media(WebKitHitTestResult* hitTestRes } /** + * webkit_hit_test_result_context_is_editable: + * @hit_test_result: a #WebKitHitTestResult + * + * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE flag is present in + * #WebKitHitTestResult:context. + * + * Returns: %TRUE if there's an editable element at the coordinates of the @hit_test_result, + * or %FALSE otherwise + */ +gboolean webkit_hit_test_result_context_is_editable(WebKitHitTestResult* hitTestResult) +{ + g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE); + + return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE; +} + +/** * webkit_hit_test_result_get_link_uri: * @hit_test_result: a #WebKitHitTestResult * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h index d8916e5f3..01e66c964 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h @@ -46,6 +46,7 @@ typedef struct _WebKitHitTestResultPrivate WebKitHitTestResultPrivate; * @WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK: a hyperlink element. * @WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE: an image element. * @WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA: a video or audio element. + * @WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE: an editable element * * Enum values with flags representing the context of a #WebKitHitTestResult. */ @@ -54,7 +55,8 @@ typedef enum WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT = 1 << 1, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK = 1 << 2, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE = 1 << 3, - WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA = 1 << 4 + WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA = 1 << 4, + WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE = 1 << 5 } WebKitHitTestResultContext; struct _WebKitHitTestResult { @@ -82,6 +84,9 @@ webkit_hit_test_result_context_is_image (WebKitHitTestResult *hit_test_resul WEBKIT_API gboolean webkit_hit_test_result_context_is_media (WebKitHitTestResult *hit_test_result); +WEBKIT_API gboolean +webkit_hit_test_result_context_is_editable (WebKitHitTestResult *hit_test_result); + WEBKIT_API const gchar * webkit_hit_test_result_get_link_uri (WebKitHitTestResult *hit_test_result); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp index 158c7fc42..e30e51d46 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp @@ -149,6 +149,8 @@ void attachLoaderClientToView(WebKitWebView* webView) 0, // willGoToBackForwardListItem 0, // interactionOccurredWhileProcessUnresponsive 0, // pluginDidFail + 0, // didReceiveIntentForFrame + 0, // registerIntentServiceForFrame }; WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); WKPageSetPageLoaderClient(wkPage, &wkLoaderClient); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h index b7c537015..7fd5d7861 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h @@ -27,13 +27,18 @@ #define WebKitPrivate_h #include <WebKit2/WKAPICast.h> +#include <WebKit2/WKContextSoup.h> #include <WebKit2/WKDownload.h> #include <WebKit2/WKFindOptions.h> #include <WebKit2/WKFullScreenClientGtk.h> +#include <WebKit2/WKGeolocationManager.h> +#include <WebKit2/WKGeolocationPermissionRequest.h> +#include <WebKit2/WKGeolocationPosition.h> #include <WebKit2/WKInspector.h> #include <WebKit2/WKInspectorClientGtk.h> #include <WebKit2/WKRetainPtr.h> #include <WebKit2/WKSerializedScriptValue.h> +#include <WebKit2/WKSoupRequestManager.h> #include <WebKit2/WKString.h> #include <WebKit2/WebKit2.h> #include <glib.h> diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp new file mode 100644 index 000000000..8ea09f200 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitRequestManagerClient.h" + +#include "WebKitURISchemeRequestPrivate.h" +#include "WebKitWebContextPrivate.h" +#include <wtf/gobject/GRefPtr.h> + +using namespace WebKit; + +static void didReceiveURIRequest(WKSoupRequestManagerRef soupRequestManagerRef, WKURLRef urlRef, uint64_t requestID, const void* clientInfo) +{ + WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(clientInfo); + GRefPtr<WebKitURISchemeRequest> request = adoptGRef(webkitURISchemeRequestCreate(webContext, soupRequestManagerRef, urlRef, requestID)); + webkitWebContextReceivedURIRequest(webContext, request.get()); +} + +static void didFailToLoadURIRequest(WKSoupRequestManagerRef, uint64_t requestID, const void* clientInfo) +{ + webkitWebContextDidFailToLoadURIRequest(WEBKIT_WEB_CONTEXT(clientInfo), requestID); +} + +void attachRequestManagerClientToContext(WebKitWebContext* webContext) +{ + WKSoupRequestManagerClient wkRequestManagerClient = { + kWKSoupRequestManagerClientCurrentVersion, + webContext, // clientInfo + didReceiveURIRequest, + didFailToLoadURIRequest + }; + WKSoupRequestManagerSetClient(webkitWebContextGetRequestManager(webContext), &wkRequestManagerClient); +} + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h new file mode 100644 index 000000000..a365594f8 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitRequestManagerClient_h +#define WebKitRequestManagerClient_h + +#include "WebKitWebContext.h" + +void attachRequestManagerClientToContext(WebKitWebContext*); + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp index 2548d7b72..7d4eedfb6 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp @@ -21,6 +21,7 @@ #include "WebKitUIClient.h" #include "WebKitFileChooserRequestPrivate.h" +#include "WebKitGeolocationPermissionRequestPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" @@ -144,6 +145,12 @@ static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParameters webkitWebViewRunFileChooserRequest(WEBKIT_WEB_VIEW(clientInfo), request.get()); } +static void decidePolicyForGeolocationPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKGeolocationPermissionRequestRef request, const void* clientInfo) +{ + GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(request)); + webkitWebViewMakePermissionRequest(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get())); +} + void attachUIClientToView(WebKitWebView* webView) { WKPageUIClient wkUIClient = { @@ -178,7 +185,7 @@ void attachUIClientToView(WebKitWebView* webView) 0, // pageDidScroll 0, // exceededDatabaseQuota runOpenPanel, - 0, // decidePolicyForGeolocationPermissionRequest + decidePolicyForGeolocationPermissionRequest, 0, // headerHeight 0, // footerHeight 0, // drawHeader diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp new file mode 100644 index 000000000..e62c1faf5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitURISchemeRequest.h" + +#include "WebKitURISchemeRequestPrivate.h" +#include "WebKitWebContextPrivate.h" +#include <WebCore/GOwnPtrSoup.h> +#include <libsoup/soup.h> +#include <wtf/gobject/GRefPtr.h> +#include <wtf/text/CString.h> + +using namespace WebKit; + +static const unsigned int gReadBufferSize = 8192; + +G_DEFINE_TYPE(WebKitURISchemeRequest, webkit_uri_scheme_request, G_TYPE_OBJECT) + +struct _WebKitURISchemeRequestPrivate { + WebKitWebContext* webContext; + WKRetainPtr<WKSoupRequestManagerRef> wkRequestManager; + uint64_t requestID; + CString uri; + GOwnPtr<SoupURI> soupURI; + + GRefPtr<GInputStream> stream; + uint64_t streamLength; + GRefPtr<GCancellable> cancellable; + char readBuffer[gReadBufferSize]; + uint64_t bytesRead; + CString mimeType; +}; + +static void webkit_uri_scheme_request_init(WebKitURISchemeRequest* request) +{ + WebKitURISchemeRequestPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(request, WEBKIT_TYPE_URI_SCHEME_REQUEST, WebKitURISchemeRequestPrivate); + request->priv = priv; + new (priv) WebKitURISchemeRequestPrivate(); +} + +static void webkitURISchemeRequestFinalize(GObject* object) +{ + WEBKIT_URI_SCHEME_REQUEST(object)->priv->~WebKitURISchemeRequestPrivate(); + G_OBJECT_CLASS(webkit_uri_scheme_request_parent_class)->finalize(object); +} + +static void webkit_uri_scheme_request_class_init(WebKitURISchemeRequestClass* requestClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(requestClass); + objectClass->finalize = webkitURISchemeRequestFinalize; + g_type_class_add_private(requestClass, sizeof(WebKitURISchemeRequestPrivate)); +} + +WebKitURISchemeRequest* webkitURISchemeRequestCreate(WebKitWebContext* webContext, WKSoupRequestManagerRef wkRequestManager, WKURLRef wkURL, uint64_t requestID) +{ + WebKitURISchemeRequest* request = WEBKIT_URI_SCHEME_REQUEST(g_object_new(WEBKIT_TYPE_URI_SCHEME_REQUEST, NULL)); + request->priv->webContext = webContext; + request->priv->wkRequestManager = wkRequestManager; + request->priv->uri = toImpl(wkURL)->string().utf8(); + request->priv->requestID = requestID; + return request; +} + +uint64_t webkitURISchemeRequestGetID(WebKitURISchemeRequest* request) +{ + return request->priv->requestID; +} + +void webkitURISchemeRequestCancel(WebKitURISchemeRequest* request) +{ + if (request->priv->cancellable.get()) + g_cancellable_cancel(request->priv->cancellable.get()); +} + +/** + * webkit_uri_scheme_request_get_scheme: + * @request: a #WebKitURISchemeRequest + * + * Get the URI scheme of @request + * + * Returns: the URI scheme of @request + */ +const char* webkit_uri_scheme_request_get_scheme(WebKitURISchemeRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_URI_SCHEME_REQUEST(request), 0); + + if (!request->priv->soupURI) + request->priv->soupURI.set(soup_uri_new(request->priv->uri.data())); + return request->priv->soupURI->scheme; +} + +/** + * webkit_uri_scheme_request_get_uri: + * @request: a #WebKitURISchemeRequest + * + * Get the URI of @request + * + * Returns: the full URI of @request + */ +const char* webkit_uri_scheme_request_get_uri(WebKitURISchemeRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_URI_SCHEME_REQUEST(request), 0); + + return request->priv->uri.data(); +} + +/** + * webkit_uri_scheme_request_get_path: + * @request: a #WebKitURISchemeRequest + * + * Get the URI path of @request + * + * Returns: the URI path of @request + */ +const char* webkit_uri_scheme_request_get_path(WebKitURISchemeRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_URI_SCHEME_REQUEST(request), 0); + + if (!request->priv->soupURI) + request->priv->soupURI.set(soup_uri_new(request->priv->uri.data())); + return request->priv->soupURI->path; +} + +static void webkitURISchemeRequestReadCallback(GInputStream* inputStream, GAsyncResult* result, WebKitURISchemeRequest* schemeRequest) +{ + GRefPtr<WebKitURISchemeRequest> request = adoptGRef(schemeRequest); + gssize bytesRead = g_input_stream_read_finish(inputStream, result, 0); + // FIXME: notify the WebProcess that we failed to read from the user stream. + if (bytesRead == -1) { + webkitWebContextDidFinishURIRequest(request->priv->webContext, request->priv->requestID); + return; + } + + WebKitURISchemeRequestPrivate* priv = request->priv; + WKRetainPtr<WKDataRef> wkData(AdoptWK, WKDataCreate(bytesRead ? reinterpret_cast<const unsigned char*>(priv->readBuffer) : 0, bytesRead)); + if (!priv->bytesRead) { + // First chunk read. In case of empty reply an empty WKDataRef is sent to the WebProcess. + WKRetainPtr<WKStringRef> wkMimeType = !priv->mimeType.isNull() ? adoptWK(WKStringCreateWithUTF8CString(priv->mimeType.data())) : 0; + WKSoupRequestManagerDidHandleURIRequest(priv->wkRequestManager.get(), wkData.get(), priv->streamLength, wkMimeType.get(), priv->requestID); + } else if (bytesRead || (!bytesRead && !priv->streamLength)) { + // Subsequent chunk read. We only send an empty WKDataRef to the WebProcess when stream length is unknown. + WKSoupRequestManagerDidReceiveURIRequestData(priv->wkRequestManager.get(), wkData.get(), priv->requestID); + } + + if (!bytesRead) { + webkitWebContextDidFinishURIRequest(request->priv->webContext, request->priv->requestID); + return; + } + + priv->bytesRead += bytesRead; + g_input_stream_read_async(inputStream, priv->readBuffer, gReadBufferSize, G_PRIORITY_DEFAULT, priv->cancellable.get(), + reinterpret_cast<GAsyncReadyCallback>(webkitURISchemeRequestReadCallback), g_object_ref(request.get())); +} + +/** + * webkit_uri_scheme_request_finish: + * @request: a #WebKitURISchemeRequest + * @stream: a #GInputStream to read the contents of the request + * @stream_length: the length of the stream or -1 if not known + * @mime_type: (allow-none): the content type of the stream or %NULL if not known + * + * Finish a #WebKitURISchemeRequest by setting the contents of the request and its mime type. + */ +void webkit_uri_scheme_request_finish(WebKitURISchemeRequest* request, GInputStream* inputStream, gint64 streamLength, const gchar* mimeType) +{ + g_return_if_fail(WEBKIT_IS_URI_SCHEME_REQUEST(request)); + g_return_if_fail(G_IS_INPUT_STREAM(inputStream)); + g_return_if_fail(streamLength == -1 || streamLength >= 0); + + request->priv->stream = inputStream; + // We use -1 in the API for consistency with soup when the content length is not known, but 0 internally. + request->priv->streamLength = streamLength == -1 ? 0 : streamLength; + request->priv->cancellable = adoptGRef(g_cancellable_new()); + request->priv->bytesRead = 0; + request->priv->mimeType = mimeType; + g_input_stream_read_async(inputStream, request->priv->readBuffer, gReadBufferSize, G_PRIORITY_DEFAULT, request->priv->cancellable.get(), + reinterpret_cast<GAsyncReadyCallback>(webkitURISchemeRequestReadCallback), g_object_ref(request)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.h new file mode 100644 index 000000000..34f214489 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitURISchemeRequest_h +#define WebKitURISchemeRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_URI_SCHEME_REQUEST (webkit_uri_scheme_request_get_type()) +#define WEBKIT_URI_SCHEME_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_URI_SCHEME_REQUEST, WebKitURISchemeRequest)) +#define WEBKIT_IS_URI_SCHEME_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_URI_SCHEME_REQUEST)) +#define WEBKIT_URI_SCHEME_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_URI_SCHEME_REQUEST, WebKitURISchemeRequestClass)) +#define WEBKIT_IS_URI_SCHEME_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_URI_SCHEME_REQUEST)) +#define WEBKIT_URI_SCHEME_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_URI_SCHEME_REQUEST, WebKitURISchemeRequestClass)) + +typedef struct _WebKitURISchemeRequest WebKitURISchemeRequest; +typedef struct _WebKitURISchemeRequestClass WebKitURISchemeRequestClass; +typedef struct _WebKitURISchemeRequestPrivate WebKitURISchemeRequestPrivate; + +struct _WebKitURISchemeRequest { + GObject parent; + + WebKitURISchemeRequestPrivate *priv; +}; + +struct _WebKitURISchemeRequestClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_uri_scheme_request_get_type (void); + +WEBKIT_API const gchar * +webkit_uri_scheme_request_get_scheme (WebKitURISchemeRequest *request); + +WEBKIT_API const gchar * +webkit_uri_scheme_request_get_uri (WebKitURISchemeRequest *request); + +WEBKIT_API const gchar * +webkit_uri_scheme_request_get_path (WebKitURISchemeRequest *request); + +WEBKIT_API void +webkit_uri_scheme_request_finish (WebKitURISchemeRequest *request, + GInputStream *stream, + gint64 stream_length, + const gchar *mime_type); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h new file mode 100644 index 000000000..149813def --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitURISchemeRequestPrivate_h +#define WebKitURISchemeRequestPrivate_h + +#include "WebKitPrivate.h" +#include "WebKitURISchemeRequest.h" +#include "WebKitWebContext.h" +#include <WebKit2/WKSoupRequestManager.h> + +WebKitURISchemeRequest* webkitURISchemeRequestCreate(WebKitWebContext*, WKSoupRequestManagerRef, WKURLRef, uint64_t requestID); +uint64_t webkitURISchemeRequestGetID(WebKitURISchemeRequest*); +void webkitURISchemeRequestCancel(WebKitURISchemeRequest*); + +#endif // WebKitURISchemeRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.cpp new file mode 100644 index 000000000..4ef62e372 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitVersion.h" + +/** + * webkit_get_major_version: + * + * Returns the major version number of the WebKit library. + * (e.g. in WebKit version 1.8.3 this is 1.) + * + * This function is in the library, so it represents the WebKit library + * your code is running against. Contrast with the #WEBKIT_MAJOR_VERSION + * macro, which represents the major version of the WebKit headers you + * have included when compiling your code. + * + * Returns: the major version number of the WebKit library + */ +guint webkit_get_major_version(void) +{ + return WEBKIT_MAJOR_VERSION; +} + +/** + * webkit_get_minor_version: + * + * Returns the minor version number of the WebKit library. + * (e.g. in WebKit version 1.8.3 this is 8.) + * + * This function is in the library, so it represents the WebKit library + * your code is running against. Contrast with the #WEBKIT_MINOR_VERSION + * macro, which represents the minor version of the WebKit headers you + * have included when compiling your code. + * + * Returns: the minor version number of the WebKit library + */ +guint webkit_get_minor_version(void) +{ + return WEBKIT_MINOR_VERSION; +} + +/** + * webkit_get_micro_version: + * + * Returns the micro version number of the WebKit library. + * (e.g. in WebKit version 1.8.3 this is 3.) + * + * This function is in the library, so it represents the WebKit library + * your code is running against. Contrast with the #WEBKIT_MICRO_VERSION + * macro, which represents the micro version of the WebKit headers you + * have included when compiling your code. + * + * Returns: the micro version number of the WebKit library + */ +guint webkit_get_micro_version(void) +{ + return WEBKIT_MICRO_VERSION; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in new file mode 100644 index 000000000..81ef5179a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitVersion_h +#define WebKitVersion_h + +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +/** + * WEBKIT_MAJOR_VERSION: + * + * Like webkit_get_major_version(), but from the headers used at + * application compile time, rather than from the library linked + * against at application run time. + */ +#define WEBKIT_MAJOR_VERSION (@WEBKIT_MAJOR_VERSION@) + +/** + * WEBKIT_MINOR_VERSION: + * + * Like webkit_get_minor_version(), but from the headers used at + * application compile time, rather than from the library linked + * against at application run time. + */ +#define WEBKIT_MINOR_VERSION (@WEBKIT_MINOR_VERSION@) + +/** + * WEBKIT_MICRO_VERSION: + * + * Like webkit_get_micro_version(), but from the headers used at + * application compile time, rather than from the library linked + * against at application run time. + */ +#define WEBKIT_MICRO_VERSION (@WEBKIT_MICRO_VERSION@) + +/** + * WEBKIT_CHECK_VERSION: + * @major: major version (e.g. 1 for version 1.2.5) + * @minor: minor version (e.g. 2 for version 1.2.5) + * @micro: micro version (e.g. 5 for version 1.2.5) + * + * Returns: %TRUE if the version of the WebKit header files + * is the same as or newer than the passed-in version. + */ +#define WEBKIT_CHECK_VERSION(major, minor, micro) \ + (WEBKIT_MAJOR_VERSION > (major) || \ + (WEBKIT_MAJOR_VERSION == (major) && WEBKIT_MINOR_VERSION > (minor)) || \ + (WEBKIT_MAJOR_VERSION == (major) && WEBKIT_MINOR_VERSION == (minor) && \ + WEBKIT_MICRO_VERSION >= (micro))) + +WEBKIT_API guint +webkit_get_major_version (void); + +WEBKIT_API guint +webkit_get_minor_version (void); + +WEBKIT_API guint +webkit_get_micro_version (void); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp index 681c0d12b..372f46637 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp @@ -24,8 +24,11 @@ #include "WebKitCookieManagerPrivate.h" #include "WebKitDownloadClient.h" #include "WebKitDownloadPrivate.h" +#include "WebKitGeolocationProvider.h" #include "WebKitPluginPrivate.h" #include "WebKitPrivate.h" +#include "WebKitRequestManagerClient.h" +#include "WebKitURISchemeRequestPrivate.h" #include "WebKitWebContextPrivate.h" #include <WebCore/FileSystem.h> #include <wtf/HashMap.h> @@ -40,10 +43,35 @@ enum { LAST_SIGNAL }; +struct WebKitURISchemeHandler { + WebKitURISchemeHandler() + : callback(0) + , userData(0) + { + } + WebKitURISchemeHandler(WebKitURISchemeRequestCallback callback, void* userData) + : callback(callback) + , userData(userData) + { + } + + WebKitURISchemeRequestCallback callback; + void* userData; +}; + +typedef HashMap<String, WebKitURISchemeHandler> URISchemeHandlerMap; +typedef HashMap<uint64_t, GRefPtr<WebKitURISchemeRequest> > URISchemeRequestMap; + struct _WebKitWebContextPrivate { WKRetainPtr<WKContextRef> context; GRefPtr<WebKitCookieManager> cookieManager; + WKRetainPtr<WKSoupRequestManagerRef> requestManager; + URISchemeHandlerMap uriSchemeHandlers; + URISchemeRequestMap uriSchemeRequests; +#if ENABLE(GEOLOCATION) + RefPtr<WebKitGeolocationProvider> geolocationProvider; +#endif }; static guint signals[LAST_SIGNAL] = { 0, }; @@ -91,8 +119,14 @@ static gpointer createDefaultWebContext(gpointer) { static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL))); webContext->priv->context = WKContextGetSharedProcessContext(); + webContext->priv->requestManager = WKContextGetSoupRequestManager(webContext->priv->context.get()); WKContextSetCacheModel(webContext->priv->context.get(), kWKCacheModelPrimaryWebBrowser); attachDownloadClientToContext(webContext.get()); + attachRequestManagerClientToContext(webContext.get()); +#if ENABLE(GEOLOCATION) + WKGeolocationManagerRef wkGeolocationManager = WKContextGetGeolocationManager(webContext->priv->context.get()); + webContext->priv->geolocationProvider = WebKitGeolocationProvider::create(wkGeolocationManager); +#endif return webContext.get(); } @@ -317,6 +351,59 @@ GList* webkit_web_context_get_plugins_finish(WebKitWebContext* context, GAsyncRe return plugins; } +/** + * webkit_web_context_register_uri_scheme: + * @context: a #WebKitWebContext + * @scheme: the network scheme to register + * @callback: a #WebKitURISchemeRequestCallback + * @user_data: data to pass to callback function + * + * Register @scheme in @context, so that when an URI request with @scheme is made in the + * #WebKitWebContext, the #WebKitURISchemeRequestCallback registered will be called with a + * #WebKitURISchemeRequest. + * It is possible to handle URI scheme requests asynchronously, by calling g_object_ref() on the + * #WebKitURISchemeRequest and calling webkit_uri_scheme_request_finish() later when the data of + * the request is available. + * + * <informalexample><programlisting> + * static void + * about_uri_scheme_request_cb (WebKitURISchemeRequest *request, + * gpointer user_data) + * { + * GInputStream *stream; + * gsize stream_length; + * const gchar *path; + * + * path = webkit_uri_scheme_request_get_path (request); + * if (!g_strcmp0 (path, "plugins")) { + * /<!-- -->* Create a GInputStream with the contents of plugins about page, and set its length to stream_length *<!-- -->/ + * } else if (!g_strcmp0 (path, "memory")) { + * /<!-- -->* Create a GInputStream with the contents of memory about page, and set its length to stream_length *<!-- -->/ + * } else if (!g_strcmp0 (path, "applications")) { + * /<!-- -->* Create a GInputStream with the contents of applications about page, and set its length to stream_length *<!-- -->/ + * } else { + * gchar *contents; + * + * contents = g_strdup_printf ("<html><body><p>Invalid about:%s page</p></body></html>", path); + * stream_length = strlen (contents); + * stream = g_memory_input_stream_new_from_data (contents, stream_length, g_free); + * } + * webkit_uri_scheme_request_finish (request, stream, stream_length, "text/html"); + * g_object_unref (stream); + * } + * </programlisting></informalexample> + */ +void webkit_web_context_register_uri_scheme(WebKitWebContext* context, const char* scheme, WebKitURISchemeRequestCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); + g_return_if_fail(scheme); + g_return_if_fail(callback); + + context->priv->uriSchemeHandlers.set(String::fromUTF8(scheme), WebKitURISchemeHandler(callback, userData)); + WKRetainPtr<WKStringRef> wkScheme(AdoptWK, WKStringCreateWithUTF8CString(scheme)); + WKSoupRequestManagerRegisterURIScheme(context->priv->requestManager.get(), wkScheme.get()); +} + WebKitDownload* webkitWebContextGetOrCreateDownload(WKDownloadRef wkDownload) { GRefPtr<WebKitDownload> download = downloadsMap().get(wkDownload); @@ -345,3 +432,30 @@ WKContextRef webkitWebContextGetWKContext(WebKitWebContext* context) return context->priv->context.get(); } +WKSoupRequestManagerRef webkitWebContextGetRequestManager(WebKitWebContext* context) +{ + return context->priv->requestManager.get(); +} + +void webkitWebContextReceivedURIRequest(WebKitWebContext* context, WebKitURISchemeRequest* request) +{ + WebKitURISchemeHandler handler = context->priv->uriSchemeHandlers.get(webkit_uri_scheme_request_get_scheme(request)); + if (!handler.callback) + return; + + context->priv->uriSchemeRequests.set(webkitURISchemeRequestGetID(request), request); + handler.callback(request, handler.userData); +} + +void webkitWebContextDidFailToLoadURIRequest(WebKitWebContext* context, uint64_t requestID) +{ + GRefPtr<WebKitURISchemeRequest> request = context->priv->uriSchemeRequests.get(requestID); + if (!request.get()) + return; + webkitURISchemeRequestCancel(request.get()); +} + +void webkitWebContextDidFinishURIRequest(WebKitWebContext* context, uint64_t requestID) +{ + context->priv->uriSchemeRequests.remove(requestID); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h index 02ef73d43..1325017d1 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h @@ -28,6 +28,7 @@ #include <webkit2/WebKitCookieManager.h> #include <webkit2/WebKitDefines.h> #include <webkit2/WebKitDownload.h> +#include <webkit2/WebKitURISchemeRequest.h> G_BEGIN_DECLS @@ -58,6 +59,17 @@ typedef enum { WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER } WebKitCacheModel; +/** + * WebKitURISchemeRequestCallback: + * @request: the #WebKitURISchemeRequest + * @user_data: user data passed to the callback + * + * Type definition for a function that will be called back when an URI request is + * made for a user registered URI scheme. + */ +typedef void (* WebKitURISchemeRequestCallback) (WebKitURISchemeRequest *request, + gpointer user_data); + typedef struct _WebKitWebContext WebKitWebContext; typedef struct _WebKitWebContextClass WebKitWebContextClass; typedef struct _WebKitWebContextPrivate WebKitWebContextPrivate; @@ -86,33 +98,37 @@ WEBKIT_API WebKitWebContext * webkit_web_context_get_default (void); WEBKIT_API void -webkit_web_context_set_cache_model (WebKitWebContext *context, - WebKitCacheModel cache_model); +webkit_web_context_set_cache_model (WebKitWebContext *context, + WebKitCacheModel cache_model); WEBKIT_API WebKitCacheModel -webkit_web_context_get_cache_model (WebKitWebContext *context); +webkit_web_context_get_cache_model (WebKitWebContext *context); WEBKIT_API WebKitDownload * -webkit_web_context_download_uri (WebKitWebContext *context, - const gchar *uri); +webkit_web_context_download_uri (WebKitWebContext *context, + const gchar *uri); WEBKIT_API WebKitCookieManager * -webkit_web_context_get_cookie_manager (WebKitWebContext *context); +webkit_web_context_get_cookie_manager (WebKitWebContext *context); WEBKIT_API void -webkit_web_context_set_additional_plugins_directory (WebKitWebContext *context, - const gchar *directory); +webkit_web_context_set_additional_plugins_directory (WebKitWebContext *context, + const gchar *directory); WEBKIT_API void -webkit_web_context_get_plugins (WebKitWebContext *context, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +webkit_web_context_get_plugins (WebKitWebContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); WEBKIT_API GList * -webkit_web_context_get_plugins_finish (WebKitWebContext *context, - GAsyncResult *result, - GError **error); - +webkit_web_context_get_plugins_finish (WebKitWebContext *context, + GAsyncResult *result, + GError **error); +WEBKIT_API void +webkit_web_context_register_uri_scheme (WebKitWebContext *context, + const gchar *scheme, + WebKitURISchemeRequestCallback callback, + gpointer user_data); G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h index d2dd81361..9e5536b3a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h @@ -26,16 +26,17 @@ #ifndef WebKitWebContextPrivate_h #define WebKitWebContextPrivate_h +#include "WebKitPrivate.h" +#include "WebKitURISchemeRequest.h" #include "WebKitWebContext.h" -#include <WebKit2/WebKit2.h> - -G_BEGIN_DECLS WKContextRef webkitWebContextGetWKContext(WebKitWebContext*); WebKitDownload* webkitWebContextGetOrCreateDownload(WKDownloadRef); void webkitWebContextRemoveDownload(WKDownloadRef); void webkitWebContextDownloadStarted(WebKitWebContext*, WebKitDownload*); - -G_END_DECLS +WKSoupRequestManagerRef webkitWebContextGetRequestManager(WebKitWebContext*); +void webkitWebContextReceivedURIRequest(WebKitWebContext*, WebKitURISchemeRequest*); +void webkitWebContextDidFailToLoadURIRequest(WebKitWebContext*, uint64_t requestID); +void webkitWebContextDidFinishURIRequest(WebKitWebContext*, uint64_t requestID); #endif // WebKitWebContextPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp index 938f95fd1..7f5764e7d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp @@ -21,7 +21,10 @@ #include "config.h" #include "WebKitWebView.h" +#include "WebContextMenuItem.h" +#include "WebContextMenuItemData.h" #include "WebKitBackForwardListPrivate.h" +#include "WebKitContextMenuClient.h" #include "WebKitEnumTypes.h" #include "WebKitError.h" #include "WebKitFullscreenClient.h" @@ -295,6 +298,7 @@ static void webkitWebViewConstructed(GObject* object) attachPolicyClientToPage(webView); attachResourceLoadClientToView(webView); attachFullScreenClientToView(webView); + attachContextMenuClientToView(webView); WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase); priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page)))); @@ -1168,6 +1172,54 @@ void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChoose g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue); } +static void webkitWebViewCreateAndAppendDefaultMenuItems(WebKitWebView* webView, WKArrayRef wkProposedMenu, Vector<ContextMenuItem>& contextMenuItems) +{ + for (size_t i = 0; i < WKArrayGetSize(wkProposedMenu); ++i) { + WKContextMenuItemRef wkItem = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(wkProposedMenu, i)); + contextMenuItems.append(toImpl(wkItem)->data()->core()); + } +} + +static bool webkitWebViewShouldShowInputMethodsMenu(WebKitWebView* webView) +{ + GtkSettings* settings = gtk_widget_get_settings(GTK_WIDGET(webView)); + if (!settings) + return true; + + gboolean showInputMethodMenu; + g_object_get(settings, "gtk-show-input-method-menu", &showInputMethodMenu, NULL); + return showInputMethodMenu; +} + +static void webkitWebViewCreateAndAppendInputMethodsMenuItem(WebKitWebView* webView, Vector<ContextMenuItem>& contextMenuItems) +{ + if (!webkitWebViewShouldShowInputMethodsMenu(webView)) + return; + + GtkIMContext* imContext = webkitWebViewBaseGetIMContext(WEBKIT_WEB_VIEW_BASE(webView)); + GtkMenu* imContextMenu = GTK_MENU(gtk_menu_new()); + gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(imContext), GTK_MENU_SHELL(imContextMenu)); + ContextMenu subMenu(imContextMenu); + + ContextMenuItem separator(SeparatorType, ContextMenuItemTagNoAction, String()); + contextMenuItems.append(separator); + ContextMenuItem menuItem(SubmenuType, ContextMenuItemTagNoAction, _("Input _Methods"), &subMenu); + contextMenuItems.append(menuItem); +} + +void webkitWebViewPopulateContextMenu(WebKitWebView* webView, WKArrayRef wkProposedMenu, WKHitTestResultRef wkHitTestResult) +{ + WebContextMenuProxyGtk* contextMenu = webkitWebViewBaseGetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(webView)); + ASSERT(contextMenu); + + Vector<ContextMenuItem> contextMenuItems; + webkitWebViewCreateAndAppendDefaultMenuItems(webView, wkProposedMenu, contextMenuItems); + if (WKHitTestResultIsContentEditable(wkHitTestResult)) + webkitWebViewCreateAndAppendInputMethodsMenuItem(webView, contextMenuItems); + + contextMenu->populate(contextMenuItems); +} + /** * webkit_web_view_new: * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp index f8308aa14..a2cc1d97b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp @@ -65,6 +65,10 @@ #include "WebFullScreenManagerProxy.h" #endif +#if USE(TEXTURE_MAPPER_GL) && defined(GDK_WINDOWING_X11) +#include <gdk/gdkx.h> +#endif + using namespace WebKit; using namespace WebCore; @@ -90,6 +94,7 @@ struct _WebKitWebViewBasePrivate { #endif GtkWidget* inspectorView; unsigned inspectorViewHeight; + WebContextMenuProxyGtk* activeContextMenuProxy; }; G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER) @@ -154,6 +159,9 @@ static void webkitWebViewBaseRealize(GtkWidget* widget) gint attributesMask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, attributesMask); +#if USE(TEXTURE_MAPPER_GL) + gdk_window_ensure_native(window); +#endif gtk_widget_set_window(widget, window); gdk_window_set_user_data(window, widget); @@ -339,6 +347,13 @@ static void webkitWebViewBaseMap(GtkWidget* widget) GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->map(widget); WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); +#if USE(TEXTURE_MAPPER_GL) && defined(GDK_WINDOWING_X11) + GdkWindow* gdkWindow = gtk_widget_get_window(widget); + ASSERT(gdkWindow); + if (gdk_window_has_native(gdkWindow)) + webViewBase->priv->pageProxy->widgetMapped(GDK_WINDOW_XID(gdkWindow)); +#endif + if (!webViewBase->priv->needsResizeOnMap) return; @@ -759,3 +774,13 @@ void webkitWebViewBaseSetInspectorViewHeight(WebKitWebViewBase* webkitWebViewBas webkitWebViewBase->priv->inspectorViewHeight = height; gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase)); } + +void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase, WebContextMenuProxyGtk* contextMenuProxy) +{ + webkitWebViewBase->priv->activeContextMenuProxy = contextMenuProxy; +} + +WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase) +{ + return webkitWebViewBase->priv->activeContextMenuProxy; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h index 5e191971c..45ffbf283 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h @@ -28,6 +28,7 @@ #ifndef WebKitWebViewBasePrivate_h #define WebKitWebViewBasePrivate_h +#include "WebContextMenuProxyGtk.h" #include "WebKitPrivate.h" #include "WebKitWebViewBase.h" #include "WebPageProxy.h" @@ -46,5 +47,7 @@ void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase*); void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*); void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase*, const WKFullScreenClientGtk*); void webkitWebViewBaseSetInspectorViewHeight(WebKitWebViewBase*, unsigned height); +void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase*, WebContextMenuProxyGtk*); +WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase*); #endif // WebKitWebViewBasePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h index 6ab374551..aedcdee6e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h @@ -53,5 +53,6 @@ void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIden WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView*, uint64_t resourceIdentifier); bool webkitWebViewEnterFullScreen(WebKitWebView*); bool webkitWebViewLeaveFullScreen(WebKitWebView*); +void webkitWebViewPopulateContextMenu(WebKitWebView*, WKArrayRef proposedMenu, WKHitTestResultRef); #endif // WebKitWebViewPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml index 90005acb2..c2eebf36c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml @@ -22,6 +22,7 @@ <xi:include href="xml/WebKitWindowProperties.xml"/> <xi:include href="xml/WebKitDownload.xml"/> <xi:include href="xml/WebKitPermissionRequest.xml"/> + <xi:include href="xml/WebKitGeolocationPermissionRequest.xml"/> <xi:include href="xml/WebKitPolicyDecision.xml"/> <xi:include href="xml/WebKitNavigationPolicyDecision.xml"/> <xi:include href="xml/WebKitResponsePolicyDecision.xml"/> @@ -34,6 +35,8 @@ <xi:include href="xml/WebKitCookieManager.xml"/> <xi:include href="xml/WebKitPlugin.xml"/> <xi:include href="xml/WebKitWebInspector.xml"/> + <xi:include href="xml/WebKitURISchemeRequest.xml"/> + <xi:include href="xml/WebKitVersion.xml"/> </chapter> <index id="index-all"> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt index 6dde0866d..1b97de88f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt @@ -33,6 +33,10 @@ webkit_web_context_set_additional_plugins_directory webkit_web_context_get_plugins webkit_web_context_get_plugins_finish +<SUBSECTION URI Scheme> +WebKitURISchemeRequestCallback +webkit_web_context_register_uri_scheme + <SUBSECTION Standard> WebKitWebContextClass WEBKIT_WEB_CONTEXT @@ -355,6 +359,7 @@ webkit_download_get_response webkit_download_cancel webkit_download_get_estimated_progress webkit_download_get_elapsed_time +webkit_download_get_received_data_length <SUBSECTION Standard> WebKitDownloadClass @@ -388,6 +393,24 @@ webkit_permission_request_get_type </SECTION> <SECTION> +<FILE>WebKitGeolocationPermissionRequest</FILE> +WebKitGeolocationPermissionRequest + +<SUBSECTION Standard> +WebKitGeolocationPermissionRequestClass +WEBKIT_TYPE_GEOLOCATION_PERMISSION_REQUEST +WEBKIT_GEOLOCATION_PERMISSION_REQUEST +WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST +WEBKIT_GEOLOCATION_PERMISSION_REQUEST_CLASS +WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST_CLASS +WEBKIT_GEOLOCATION_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitGeolocationPermissionRequestPrivate +webkit_geolocation_permission_request_get_type +</SECTION> + +<SECTION> <FILE>WebKitPolicyDecision</FILE> WebKitPolicyDecision webkit_policy_decision_download @@ -460,6 +483,7 @@ webkit_hit_test_result_get_context webkit_hit_test_result_context_is_link webkit_hit_test_result_context_is_image webkit_hit_test_result_context_is_media +webkit_hit_test_result_context_is_editable webkit_hit_test_result_get_link_uri webkit_hit_test_result_get_link_title webkit_hit_test_result_get_link_label @@ -685,3 +709,38 @@ WEBKIT_WEB_INSPECTOR_GET_CLASS webkit_web_inspector_get_type WebKitWebInspectorPrivate </SECTION> + +<SECTION> +<FILE>WebKitURISchemeRequest</FILE> +WebKitURISchemeRequest +webkit_uri_scheme_request_get_scheme +webkit_uri_scheme_request_get_uri +webkit_uri_scheme_request_get_path +webkit_uri_scheme_request_finish + +<SUBSECTION Standard> +WebKitURISchemeRequestClass +WEBKIT_TYPE_URI_SCHEME_REQUEST +WEBKIT_URI_SCHEME_REQUEST +WEBKIT_IS_URI_SCHEME_REQUEST +WEBKIT_URI_SCHEME_REQUEST_CLASS +WEBKIT_IS_URI_SCHEME_REQUEST_CLASS +WEBKIT_URI_SCHEME_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitURISchemeRequestPrivate +webkit_uri_scheme_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitVersion</FILE> +webkit_get_major_version +webkit_get_minor_version +webkit_get_micro_version + +<SUBSECTION> +WEBKIT_MAJOR_VERSION +WEBKIT_MINOR_VERSION +WEBKIT_MICRO_VERSION +WEBKIT_CHECK_VERSION +</SECTION> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types index 92b6fb400..d155982f2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types @@ -18,3 +18,4 @@ webkit_cookie_manager_get_type webkit_plugin_get_type webkit_mime_info_get_type webkit_web_inspector_get_type +webkit_uri_scheme_request_get_type diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am index 8fa0cd8d8..7adae8adc 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am +++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am @@ -8,6 +8,7 @@ TEST_PROGS += \ Programs/WebKit2APITests/TestLoaderClient \ Programs/WebKit2APITests/TestPrinting \ Programs/WebKit2APITests/TestResources \ + Programs/WebKit2APITests/TestWebKitVersion \ Programs/WebKit2APITests/TestWebKitFindController \ Programs/WebKit2APITests/TestWebKitPolicyClient \ Programs/WebKit2APITests/TestWebKitSettings \ @@ -160,4 +161,10 @@ Programs_WebKit2APITests_TestInspector_CPPFLAGS = \ Programs_WebKit2APITests_TestInspector_LDADD = $(webkit2_tests_ldadd) Programs_WebKit2APITests_TestInspector_LDFLAGS = $(webkit2_tests_ldflags) +Programs_WebKit2APITests_TestWebKitVersion_SOURCES = \ + Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitVersion.cpp +Programs_WebKit2APITests_TestWebKitVersion_CPPFLAGS = $(webkit2_tests_cppflags) +Programs_WebKit2APITests_TestWebKitVersion_LDADD = $(webkit2_tests_ldadd) +Programs_WebKit2APITests_TestWebKitVersion_LDFLAGS = $(webkit2_tests_ldflags) + endif # ENABLE_WEBKIT2 diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp index acec9ece1..9c3262b53 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp @@ -136,6 +136,7 @@ public: virtual void finished(WebKitDownload* download) { + g_assert_cmpuint(m_downloadSize, ==, webkit_download_get_received_data_length(download)); m_downloadEvents.append(Finished); g_main_loop_quit(m_mainLoop); } diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitVersion.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitVersion.cpp new file mode 100644 index 000000000..e747ff962 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitVersion.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "TestMain.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + + +static void testWebKitVersion(Test*, gconstpointer) +{ + g_assert_cmpuint(webkit_get_major_version(), ==, WEBKIT_MAJOR_VERSION); + g_assert_cmpuint(webkit_get_minor_version(), ==, WEBKIT_MINOR_VERSION); + g_assert_cmpuint(webkit_get_micro_version(), ==, WEBKIT_MICRO_VERSION); +} + +static void testWebKitCheckVersion(Test*, gconstpointer) +{ + g_assert(WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION)); + g_assert(!WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION + 1, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION)); + g_assert(!WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION + 1, WEBKIT_MICRO_VERSION)); + g_assert(!WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION + 1)); +} + +void beforeAll() +{ + Test::add("WebKitVersion", "version", testWebKitVersion); + Test::add("WebKitVersion", "check-version", testWebKitCheckVersion); +} + +void afterAll() +{ +} diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp index 216a5c9f5..e7d43a13d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp @@ -19,10 +19,13 @@ #include "config.h" -#include "TestMain.h" +#include "LoadTrackingTest.h" #include <gtk/gtk.h> #include <webkit2/webkit2.h> +#include <wtf/HashMap.h> +#include <wtf/gobject/GOwnPtr.h> #include <wtf/gobject/GRefPtr.h> +#include <wtf/text/StringHash.h> static void testWebContextDefault(Test* test, gconstpointer) { @@ -106,10 +109,133 @@ static void testWebContextGetPlugins(PluginsTest* test, gconstpointer) g_assert_cmpstr(extensions[0], ==, "testnetscape"); } +static const char* kBarHTML = "<html><body>Bar</body></html>"; +static const char* kEchoHTMLFormat = "<html><body>%s</body></html>"; + +class URISchemeTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(URISchemeTest); + + struct URISchemeHandler { + URISchemeHandler() + : replyLength(0) + , replyWithPath(false) + { + } + + URISchemeHandler(const char* reply, int replyLength, const char* mimeType, bool replyWithPath = false) + : reply(reply) + , replyLength(replyLength) + , mimeType(mimeType) + , replyWithPath(replyWithPath) + { + } + + CString reply; + int replyLength; + CString mimeType; + bool replyWithPath; + }; + + static void uriSchemeRequestCallback(WebKitURISchemeRequest* request, gpointer userData) + { + URISchemeTest* test = static_cast<URISchemeTest*>(userData); + test->m_uriSchemeRequest = request; + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + + GRefPtr<GInputStream> inputStream = adoptGRef(g_memory_input_stream_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(inputStream.get())); + + String scheme(String::fromUTF8(webkit_uri_scheme_request_get_scheme(request))); + g_assert(!scheme.isEmpty()); + g_assert(test->m_handlersMap.contains(scheme)); + const URISchemeHandler& handler = test->m_handlersMap.get(scheme); + + if (handler.replyWithPath) { + char* replyHTML = g_strdup_printf(handler.reply.data(), webkit_uri_scheme_request_get_path(request)); + g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(inputStream.get()), replyHTML, strlen(replyHTML), g_free); + } else if (!handler.reply.isNull()) + g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(inputStream.get()), handler.reply.data(), handler.reply.length(), 0); + webkit_uri_scheme_request_finish(request, inputStream.get(), handler.replyLength, handler.mimeType.data()); + } + + void registerURISchemeHandler(const char* scheme, const char* reply, int replyLength, const char* mimeType, bool replyWithPath = false) + { + m_handlersMap.set(String::fromUTF8(scheme), URISchemeHandler(reply, replyLength, mimeType, replyWithPath)); + webkit_web_context_register_uri_scheme(webkit_web_context_get_default(), scheme, uriSchemeRequestCallback, this); + } + + static void resourceGetDataCallback(GObject* object, GAsyncResult* result, gpointer userData) + { + size_t dataSize; + GOwnPtr<GError> error; + unsigned char* data = webkit_web_resource_get_data_finish(WEBKIT_WEB_RESOURCE(object), result, &dataSize, &error.outPtr()); + g_assert(data); + + URISchemeTest* test = static_cast<URISchemeTest*>(userData); + test->m_resourceData.set(reinterpret_cast<char*>(data)); + test->m_resourceDataSize = dataSize; + g_main_loop_quit(test->m_mainLoop); + } + + const char* mainResourceData(size_t& mainResourceDataSize) + { + m_resourceDataSize = 0; + m_resourceData.clear(); + WebKitWebResource* resource = webkit_web_view_get_main_resource(m_webView); + g_assert(resource); + + webkit_web_resource_get_data(resource, 0, resourceGetDataCallback, this); + g_main_loop_run(m_mainLoop); + + mainResourceDataSize = m_resourceDataSize; + return m_resourceData.get(); + } + + GOwnPtr<char> m_resourceData; + size_t m_resourceDataSize; + GRefPtr<WebKitURISchemeRequest> m_uriSchemeRequest; + HashMap<String, URISchemeHandler> m_handlersMap; +}; + +static void testWebContextURIScheme(URISchemeTest* test, gconstpointer) +{ + test->registerURISchemeHandler("foo", kBarHTML, strlen(kBarHTML), "text/html"); + test->loadURI("foo:blank"); + test->waitUntilLoadFinished(); + size_t mainResourceDataSize = 0; + const char* mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(kBarHTML)); + g_assert(!strncmp(mainResourceData, kBarHTML, mainResourceDataSize)); + + test->registerURISchemeHandler("echo", kEchoHTMLFormat, -1, "text/html", true); + test->loadURI("echo:hello world"); + test->waitUntilLoadFinished(); + GOwnPtr<char> echoHTML(g_strdup_printf(kEchoHTMLFormat, webkit_uri_scheme_request_get_path(test->m_uriSchemeRequest.get()))); + mainResourceDataSize = 0; + mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(echoHTML.get())); + g_assert(!strncmp(mainResourceData, echoHTML.get(), mainResourceDataSize)); + + test->registerURISchemeHandler("nomime", kBarHTML, -1, 0); + test->m_loadEvents.clear(); + test->loadURI("nomime:foo bar"); + test->waitUntilLoadFinished(); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + + test->registerURISchemeHandler("empty", 0, 0, "text/html"); + test->m_loadEvents.clear(); + test->loadURI("empty:nothing"); + test->waitUntilLoadFinished(); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadFailed)); +} + void beforeAll() { Test::add("WebKitWebContext", "default-context", testWebContextDefault); PluginsTest::add("WebKitWebContext", "get-plugins", testWebContextGetPlugins); + URISchemeTest::add("WebKitWebContext", "uri-scheme", testWebContextURIScheme); } void afterAll() diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp index 6ede533d4..646752974 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp @@ -19,6 +19,8 @@ #include "config.h" #include "WebViewTest.h" +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/JSValueRef.h> #include <wtf/HashSet.h> #include <wtf/gobject/GRefPtr.h> #include <wtf/text/StringHash.h> @@ -278,15 +280,30 @@ public: g_main_loop_quit(test->m_mainLoop); } + static gboolean permissionRequested(WebKitWebView*, WebKitPermissionRequest* request, UIClientTest* test) + { + g_assert(WEBKIT_IS_PERMISSION_REQUEST(request)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + + if (test->m_allowPermissionRequests) + webkit_permission_request_allow(request); + else + webkit_permission_request_deny(request); + + return TRUE; + } + UIClientTest() : m_scriptDialogType(WEBKIT_SCRIPT_DIALOG_ALERT) , m_scriptDialogConfirmed(true) + , m_allowPermissionRequests(false) , m_mouseTargetModifiers(0) { webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE); g_signal_connect(m_webView, "create", G_CALLBACK(viewCreate), this); g_signal_connect(m_webView, "script-dialog", G_CALLBACK(scriptDialog), this); g_signal_connect(m_webView, "mouse-target-changed", G_CALLBACK(mouseTargetChanged), this); + g_signal_connect(m_webView, "permission-request", G_CALLBACK(permissionRequested), this); } ~UIClientTest() @@ -314,6 +331,7 @@ public: Vector<WebViewEvents> m_webViewEvents; WebKitScriptDialogType m_scriptDialogType; bool m_scriptDialogConfirmed; + bool m_allowPermissionRequests; WindowProperties m_windowProperties; HashSet<WTF::String> m_windowPropertiesChanged; GRefPtr<WebKitHitTestResult> m_mouseTargetHitTestResult; @@ -399,6 +417,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) " <img style='position:absolute; left:1; top:10' src='0xdeadbeef' width=5 height=5></img>" " <a style='position:absolute; left:1; top:20' href='http://www.webkitgtk.org/logo' title='WebKitGTK+ Logo'><img src='0xdeadbeef' width=5 height=5></img></a>" " <video style='position:absolute; left:1; top:30' width=10 height=10 controls='controls'><source src='movie.ogg' type='video/ogg' /></video>" + " <input style='position:absolute; left:1; top:50' size='10'></input>" "</body></html>"; test->loadHtml(linksHoveredHTML, "file:///"); @@ -409,6 +428,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) g_assert(webkit_hit_test_result_context_is_link(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); g_assert_cmpstr(webkit_hit_test_result_get_link_uri(hitTestResult), ==, "http://www.webkitgtk.org/"); g_assert_cmpstr(webkit_hit_test_result_get_link_title(hitTestResult), ==, "WebKitGTK+ Title"); g_assert_cmpstr(webkit_hit_test_result_get_link_label(hitTestResult), ==, "WebKitGTK+ Website"); @@ -419,6 +439,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); g_assert(!test->m_mouseTargetModifiers); // Move over image with GDK_CONTROL_MASK. @@ -426,6 +447,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); g_assert(webkit_hit_test_result_context_is_image(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); g_assert_cmpstr(webkit_hit_test_result_get_image_uri(hitTestResult), ==, "file:///0xdeadbeef"); g_assert(test->m_mouseTargetModifiers & GDK_CONTROL_MASK); @@ -434,6 +456,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) g_assert(webkit_hit_test_result_context_is_link(hitTestResult)); g_assert(webkit_hit_test_result_context_is_image(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); g_assert_cmpstr(webkit_hit_test_result_get_link_uri(hitTestResult), ==, "http://www.webkitgtk.org/logo"); g_assert_cmpstr(webkit_hit_test_result_get_image_uri(hitTestResult), ==, "file:///0xdeadbeef"); g_assert_cmpstr(webkit_hit_test_result_get_link_title(hitTestResult), ==, "WebKitGTK+ Logo"); @@ -445,8 +468,53 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); g_assert(webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); g_assert_cmpstr(webkit_hit_test_result_get_media_uri(hitTestResult), ==, "file:///movie.ogg"); g_assert(!test->m_mouseTargetModifiers); + + // Mover over input. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(5, 55); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!test->m_mouseTargetModifiers); +} + +static void testWebViewPermissionRequests(UIClientTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + static const char* geolocationRequestHTML = + "<html>" + " <script>" + " function runTest()" + " {" + " navigator.geolocation.getCurrentPosition(function(p) { document.title = \"OK\" }," + " function(e) { document.title = e.code });" + " }" + " </script>" + " <body onload='runTest();'></body>" + "</html>"; + + // Test denying a permission request. + test->m_allowPermissionRequests = false; + test->loadHtml(geolocationRequestHTML, 0); + test->waitUntilTitleChanged(); + + // According to the Geolocation API specification, '1' is the + // error code returned for the PERMISSION_DENIED error. + // http://dev.w3.org/geo/api/spec-source.html#position_error_interface + const gchar* result = webkit_web_view_get_title(test->m_webView); + g_assert_cmpstr(result, ==, "1"); + + // Test allowing a permission request. + test->m_allowPermissionRequests = true; + test->loadHtml(geolocationRequestHTML, 0); + test->waitUntilTitleChanged(); + + // Check that we did not get the PERMISSION_DENIED error now. + result = webkit_web_view_get_title(test->m_webView); + g_assert_cmpstr(result, !=, "1"); } static void testWebViewZoomLevel(WebViewTest* test, gconstpointer) @@ -730,6 +798,7 @@ void beforeAll() UIClientTest::add("WebKitWebView", "javascript-dialogs", testWebViewJavaScriptDialogs); UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties); UIClientTest::add("WebKitWebView", "mouse-target", testWebViewMouseTarget); + UIClientTest::add("WebKitWebView", "permission-requests", testWebViewPermissionRequests); WebViewTest::add("WebKitWebView", "zoom-level", testWebViewZoomLevel); WebViewTest::add("WebKitWebView", "run-javascript", testWebViewRunJavaScript); FileChooserTest::add("WebKitWebView", "file-chooser-request", testWebViewFileChooserRequest); diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h index cc5c349e2..bf37fcb73 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h @@ -33,6 +33,7 @@ #include <webkit2/WebKitError.h> #include <webkit2/WebKitFileChooserRequest.h> #include <webkit2/WebKitFindController.h> +#include <webkit2/WebKitGeolocationPermissionRequest.h> #include <webkit2/WebKitHitTestResult.h> #include <webkit2/WebKitJavascriptResult.h> #include <webkit2/WebKitMimeInfo.h> @@ -45,6 +46,8 @@ #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitURIResponse.h> +#include <webkit2/WebKitURISchemeRequest.h> +#include <webkit2/WebKitVersion.h> #include <webkit2/WebKitWebContext.h> #include <webkit2/WebKitWebInspector.h> #include <webkit2/WebKitWebResource.h> diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h index a9d7a9fa9..ac074e8cc 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h @@ -33,8 +33,11 @@ @class WKEditorUndoTargetObjC; @class WKView; -namespace WebKit { +namespace WebCore { +class AlternativeTextUIController; +} +namespace WebKit { class FindIndicatorWindow; class PageClientImpl : public PageClient { @@ -56,6 +59,7 @@ private: virtual bool isViewVisible(); virtual bool isViewInWindow(); virtual LayerHostingMode viewLayerHostingMode() OVERRIDE; + virtual ColorSpaceData colorSpace() OVERRIDE; virtual void processDidCrash(); virtual void pageClosed(); @@ -129,11 +133,22 @@ private: virtual WKView* wkView() const { return m_wkView; } +#if USE(DICTATION_ALTERNATIVES) + virtual uint64_t addDictationAlternatives(const RetainPtr<NSTextAlternatives>&); + virtual void removeDictationAlternatives(uint64_t dictationContext); + virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext); + virtual void dismissDictationAlternativeUI(); + virtual Vector<String> dictationAlternatives(uint64_t dictationContext); +#endif + WKView* m_wkView; RetainPtr<WKEditorUndoTargetObjC> m_undoTarget; -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if USE(AUTOCORRECTION_PANEL) CorrectionPanel m_correctionPanel; #endif +#if USE(DICTATION_ALTERNATIVES) + OwnPtr<WebCore::AlternativeTextUIController> m_alternativeTextUIController; +#endif }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm index 72ea3493e..8d0913e52 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm @@ -26,6 +26,10 @@ #import "config.h" #import "PageClientImpl.h" +#if USE(DICTATION_ALTERNATIVES) +#import <AppKit/NSTextAlternatives.h> +#endif +#import "ColorSpaceData.h" #import "DataReference.h" #import "DictionaryPopupInfo.h" #import "FindIndicator.h" @@ -37,6 +41,7 @@ #import "WebContextMenuProxyMac.h" #import "WebEditCommandProxy.h" #import "WebPopupMenuProxyMac.h" +#import <WebCore/AlternativeTextUIController.h> #import <WebCore/BitmapImage.h> #import <WebCore/Cursor.h> #import <WebCore/FloatRect.h> @@ -122,6 +127,9 @@ PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView) PageClientImpl::PageClientImpl(WKView* wkView) : m_wkView(wkView) , m_undoTarget(AdoptNS, [[WKEditorUndoTargetObjC alloc] init]) +#if USE(DICTATION_ALTERNATIVES) + , m_alternativeTextUIController(adoptPtr(new AlternativeTextUIController)) +#endif { } @@ -205,14 +213,22 @@ LayerHostingMode PageClientImpl::viewLayerHostingMode() #endif } +ColorSpaceData PageClientImpl::colorSpace() +{ + return [m_wkView _colorSpace]; +} + void PageClientImpl::processDidCrash() { [m_wkView _processDidCrash]; } - + void PageClientImpl::pageClosed() { [m_wkView _pageClosed]; +#if USE(DICTATION_ALTERNATIVES) + m_alternativeTextUIController->clear(); +#endif } void PageClientImpl::didRelaunchProcess() @@ -465,7 +481,7 @@ void PageClientImpl::dismissDictionaryLookupPanel() void PageClientImpl::showCorrectionPanel(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) { -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if USE(AUTOCORRECTION_PANEL) if (!isViewVisible() || !isViewInWindow()) return; m_correctionPanel.show(m_wkView, type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings); @@ -474,14 +490,14 @@ void PageClientImpl::showCorrectionPanel(AlternativeTextType type, const FloatRe void PageClientImpl::dismissCorrectionPanel(ReasonForDismissingAlternativeText reason) { -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if USE(AUTOCORRECTION_PANEL) m_correctionPanel.dismiss(reason); #endif } String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText reason) { -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if USE(AUTOCORRECTION_PANEL) return m_correctionPanel.dismiss(reason); #else return String(); @@ -529,4 +545,35 @@ bool PageClientImpl::executeSavedCommandBySelector(const String& selectorString) return [m_wkView _executeSavedCommandBySelector:NSSelectorFromString(selectorString)]; } +#if USE(DICTATION_ALTERNATIVES) +uint64_t PageClientImpl::addDictationAlternatives(const RetainPtr<NSTextAlternatives>& alternatives) +{ + return m_alternativeTextUIController->addAlternatives(alternatives); +} + +void PageClientImpl::removeDictationAlternatives(uint64_t dictationContext) +{ + m_alternativeTextUIController->removeAlternatives(dictationContext); +} + +void PageClientImpl::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) +{ + if (!isViewVisible() || !isViewInWindow()) + return; + m_alternativeTextUIController->showAlternatives(m_wkView, boundingBoxOfDictatedText, dictationContext, ^(NSString* acceptedAlternative){ + [m_wkView handleAcceptedAlternativeText:acceptedAlternative]; + }); +} + +Vector<String> PageClientImpl::dictationAlternatives(uint64_t dictationContext) +{ + return m_alternativeTextUIController->alternativesForContext(dictationContext); +} + +void PageClientImpl::dismissDictationAlternativeUI() +{ + m_alternativeTextUIController->dismissAlternatives(); +} +#endif + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm index 2c4341b5d..3daa08c37 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm @@ -215,11 +215,17 @@ static inline NSURL *autoreleased(WKURLRef url) case WKPaginationModeUnpaginated: mode = kWKPaginationModeUnpaginated; break; - case WKPaginationModeHorizontal: - mode = kWKPaginationModeHorizontal; + case WKPaginationModeLeftToRight: + mode = kWKPaginationModeLeftToRight; break; - case WKPaginationModeVertical: - mode = kWKPaginationModeVertical; + case WKPaginationModeRightToLeft: + mode = kWKPaginationModeRightToLeft; + break; + case WKPaginationModeTopToBottom: + mode = kWKPaginationModeTopToBottom; + break; + case WKPaginationModeBottomToTop: + mode = kWKPaginationModeBottomToTop; break; default: return; @@ -233,10 +239,14 @@ static inline NSURL *autoreleased(WKURLRef url) switch (WKPageGetPaginationMode(self._pageRef)) { case kWKPaginationModeUnpaginated: return WKPaginationModeUnpaginated; - case kWKPaginationModeHorizontal: - return WKPaginationModeHorizontal; - case kWKPaginationModeVertical: - return WKPaginationModeVertical; + case kWKPaginationModeLeftToRight: + return WKPaginationModeLeftToRight; + case kWKPaginationModeRightToLeft: + return WKPaginationModeRightToLeft; + case kWKPaginationModeTopToBottom: + return WKPaginationModeTopToBottom; + case kWKPaginationModeBottomToTop: + return WKPaginationModeBottomToTop; } ASSERT_NOT_REACHED(); diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h index c362c55c2..48fcb12f0 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h @@ -27,8 +27,10 @@ enum { WKPaginationModeUnpaginated, - WKPaginationModeHorizontal, - WKPaginationModeVertical, + WKPaginationModeLeftToRight, + WKPaginationModeRightToLeft, + WKPaginationModeTopToBottom, + WKPaginationModeBottomToTop, }; typedef NSUInteger WKBrowsingContextPaginationMode; diff --git a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.h b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.h index 91c93e592..d28beaca2 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.h +++ b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.h @@ -26,6 +26,8 @@ #ifndef WKTextInputWindowController_h #define WKTextInputWindowController_h +#if USE(APPKIT) + @class WKTextInputPanel; @interface WKTextInputWindowController : NSObject { @@ -42,4 +44,6 @@ @end +#endif // USE(APPKIT) + #endif // WKTextInputWindowController_h diff --git a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm index 2be0cfd3c..8834dcd33 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm @@ -26,6 +26,8 @@ #import "config.h" #import "WKTextInputWindowController.h" +#if USE(APPKIT) + #import <WebKitSystemInterface.h> @interface WKTextInputView : NSTextView { @@ -199,3 +201,5 @@ } @end + +#endif // USE(APPKIT) diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm index f03b9a899..aa8dc8521 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm @@ -26,7 +26,13 @@ #import "config.h" #import "WKView.h" +#if USE(DICTATION_ALTERNATIVES) +#import <AppKit/NSTextAlternatives.h> +#import <AppKit/NSAttributedString.h> +#endif + #import "AttributedString.h" +#import "ColorSpaceData.h" #import "DataReference.h" #import "DrawingAreaProxyImpl.h" #import "EditorState.h" @@ -73,6 +79,7 @@ #import <WebCore/Region.h> #import <WebCore/RunLoop.h> #import <WebCore/SharedBuffer.h> +#import <WebCore/TextAlternativeWithRange.h> #import <WebCore/WebCoreNSStringExtras.h> #import <WebCore/FileSystem.h> #import <WebKitSystemInterface.h> @@ -201,6 +208,9 @@ struct WKViewInterpretKeyEventsParameters { // We use this flag to determine when we need to paint the background (white or clear) // when the web process is unresponsive or takes too long to paint. BOOL _windowHasValidBackingStore; + + RetainPtr<NSColorSpace> _colorSpace; + RefPtr<WebCore::Image> _promisedImage; String _promisedFilename; String _promisedURL; @@ -1173,7 +1183,12 @@ static const short kIOHIDEventTypeScroll = 6; NSString *text; bool isFromInputMethod = _data->_page->editorState().hasComposition; + Vector<TextAlternativeWithRange> dictationAlternatives; + if (isAttributedString) { +#if USE(DICTATION_ALTERNATIVES) + collectDictationTextAlternatives(string, dictationAlternatives); +#endif // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data. text = [string string]; } else @@ -1195,7 +1210,11 @@ static const short kIOHIDEventTypeScroll = 6; String eventText = text; eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore - bool eventHandled = _data->_page->insertText(eventText, replacementRange.location, NSMaxRange(replacementRange)); + bool eventHandled; + if (!dictationAlternatives.isEmpty()) + eventHandled = _data->_page->insertDictatedText(eventText, replacementRange.location, NSMaxRange(replacementRange), dictationAlternatives); + else + eventHandled = _data->_page->insertText(eventText, replacementRange.location, NSMaxRange(replacementRange)); if (parameters) parameters->eventInterpretationHadSideEffects |= eventHandled; @@ -1447,7 +1466,11 @@ static const short kIOHIDEventTypeScroll = 6; if (!validAttributes) { validAttributes = [[NSArray alloc] initWithObjects: NSUnderlineStyleAttributeName, NSUnderlineColorAttributeName, - NSMarkedClauseSegmentAttributeName, nil]; + NSMarkedClauseSegmentAttributeName, +#if USE(DICTATION_ALTERNATIVES) + NSTextAlternativesAttributeName, +#endif + nil]; // NSText also supports the following attributes, but it's // hard to tell which are really required for text input to // work well; I have not seen any input method make use of them yet. @@ -1876,9 +1899,9 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl // update the active state. if ([self window]) { _data->_windowHasValidBackingStore = NO; + [self _updateWindowVisibility]; _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible | WebPageProxy::ViewIsInWindow); - [self _updateWindowVisibility]; [self _updateWindowAndViewFrames]; if (!_data->_flagsChangedEventMonitor) { @@ -1967,27 +1990,29 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl - (void)_windowDidOrderOffScreen:(NSNotification *)notification { + [self _updateWindowVisibility]; + // We want to make sure to update the active state while hidden, so since the view is about to be hidden, // we hide it first and then update the active state. _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); - [self _updateWindowVisibility]; } - (void)_windowDidOrderOnScreen:(NSNotification *)notification { + [self _updateWindowVisibility]; + // We want to make sure to update the active state while hidden, so since the view is about to become visible, // we update the active state first and then make it visible. _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); - [self _updateWindowVisibility]; } - (void)_windowDidChangeBackingProperties:(NSNotification *)notification { - CGFloat oldBackingScaleFactor = [[notification.userInfo objectForKey:backingPropertyOldScaleFactorKey] doubleValue]; + CGFloat oldBackingScaleFactor = [[notification.userInfo objectForKey:backingPropertyOldScaleFactorKey] doubleValue]; CGFloat newBackingScaleFactor = [self _intrinsicDeviceScaleFactor]; - if (oldBackingScaleFactor == newBackingScaleFactor) + if (oldBackingScaleFactor == newBackingScaleFactor) return; _data->_windowHasValidBackingStore = NO; @@ -2072,6 +2097,17 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); } +- (void)viewDidChangeBackingProperties +{ + NSColorSpace *colorSpace = [[self window] colorSpace]; + if ([colorSpace isEqualTo:_data->_colorSpace.get()]) + return; + + _data->_colorSpace = nullptr; + if (DrawingAreaProxy *drawingArea = _data->_page->drawingArea()) + drawingArea->colorSpaceDidChange(); +} + - (void)_accessibilityRegisterUIProcessTokens { // Initialize remote accessibility when the window connection has been established. @@ -2227,6 +2263,21 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I return [[self window] firstResponder] == self; } +- (WebKit::ColorSpaceData)_colorSpace +{ + if (!_data->_colorSpace) { + if ([self window]) + _data->_colorSpace = [[self window] colorSpace]; + else + _data->_colorSpace = [[NSScreen mainScreen] colorSpace]; + } + + ColorSpaceData colorSpaceData; + colorSpaceData.cgColorSpace = [_data->_colorSpace.get() CGColorSpace]; + + return colorSpaceData; +} + - (void)_processDidCrash { if (_data->_layerHostingView) @@ -2660,10 +2711,10 @@ static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension if (!matchesExtensionOrEquivalent(filename, extension)) filename = [[filename stringByAppendingString:@"."] stringByAppendingString:extension]; - [pasteboard setString:url forType:NSURLPboardType]; + [pasteboard setString:visibleUrl forType:NSStringPboardType]; [pasteboard setString:visibleUrl forType:PasteboardTypes::WebURLPboardType]; [pasteboard setString:title forType:PasteboardTypes::WebURLNamePboardType]; - [pasteboard setPropertyList:[NSArray arrayWithObjects:[NSArray arrayWithObject:url], [NSArray arrayWithObject:title], nil] forType:PasteboardTypes::WebURLsWithTitlesPboardType]; + [pasteboard setPropertyList:[NSArray arrayWithObjects:[NSArray arrayWithObject:visibleUrl], [NSArray arrayWithObject:title], nil] forType:PasteboardTypes::WebURLsWithTitlesPboardType]; [pasteboard setPropertyList:[NSArray arrayWithObject:extension] forType:NSFilesPromisePboardType]; if (archiveBuffer) @@ -2874,9 +2925,19 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) return _data->_spellCheckerDocumentTag; } -- (void)handleCorrectionPanelResult:(NSString*)result +- (void)handleAcceptedAlternativeText:(NSString*)text +{ + _data->_page->handleAlternativeTextUIResult(text); +} + +- (void)_setSuppressVisibilityUpdates:(BOOL)suppressVisibilityUpdates +{ + _data->_page->setSuppressVisibilityUpdates(suppressVisibilityUpdates); +} + +- (BOOL)_suppressVisibilityUpdates { - _data->_page->handleAlternativeTextUIResult(result); + return _data->_page->suppressVisibilityUpdates(); } @end diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h index 6b6eb6bf4..2e99e7976 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h @@ -43,6 +43,7 @@ namespace WebKit { class DrawingAreaProxy; class FindIndicator; class LayerTreeContext; + struct ColorSpaceData; struct EditorState; } @@ -87,6 +88,8 @@ namespace WebKit { - (void)_didChangeScrollbarsForMainFrame; +- (WebKit::ColorSpaceData)_colorSpace; + #if ENABLE(FULLSCREEN_API) - (BOOL)hasFullScreenWindowController; - (WKFullScreenWindowController*)fullScreenWindowController; @@ -96,6 +99,9 @@ namespace WebKit { - (void)_cacheWindowBottomCornerRect; - (NSInteger)spellCheckerDocumentTag; -- (void)handleCorrectionPanelResult:(NSString*)result; +- (void)handleAcceptedAlternativeText:(NSString*)text; + +- (void)_setSuppressVisibilityUpdates:(BOOL)suppressVisibilityUpdates; +- (BOOL)_suppressVisibilityUpdates; @end diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h index 4c32d0f1b..2f87acf1e 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h @@ -28,7 +28,7 @@ #include "qwebkitglobal.h" #include <QNetworkAccessManager> #include <QObject> -#include <QWeakPointer> +#include <QPointer> #include <QtQml/qqmllist.h> #include <QtQuick/qquickitem.h> @@ -58,7 +58,7 @@ private: WTF::RefPtr<WebKit::QtRefCountedNetworkRequestData> m_networkRequestData; WTF::RefPtr<WebKit::QtRefCountedNetworkReplyData> m_networkReplyData; QVariant m_data; - QWeakPointer<QQuickWebViewExperimental> m_webViewExperimental; + QPointer<QQuickWebViewExperimental> m_webViewExperimental; }; QML_DECLARE_TYPE(QQuickNetworkReply) diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h index e4be37364..ba0e42eda 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h @@ -26,7 +26,7 @@ namespace WebKit { class WebPageProxy; -class QtViewportInteractionEngine; +class QtViewportHandler; class QtWebPageEventHandler; } diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index 7fc2e8728..c52da4df6 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -25,7 +25,7 @@ #include "DrawingAreaProxyImpl.h" #include "QtDialogRunner.h" #include "QtDownloadManager.h" -#include "QtViewportInteractionEngine.h" +#include "QtViewportHandler.h" #include "QtWebContext.h" #include "QtWebError.h" #include "QtWebIconDatabaseClient.h" @@ -34,6 +34,8 @@ #include "QtWebPagePolicyClient.h" #include "UtilsQt.h" #include "WebBackForwardList.h" +#include "WebInspectorProxy.h" +#include "WebInspectorServer.h" #if ENABLE(FULLSCREEN_API) #include "WebFullScreenManagerProxy.h" #endif @@ -775,6 +777,8 @@ void QQuickWebViewLegacyPrivate::updateViewportSize() { Q_Q(QQuickWebView); QSize viewportSize = q->boundingRect().size().toSize(); + if (viewportSize.isEmpty()) + return; pageView->setContentsSize(viewportSize); // The fixed layout is handled by the FrameView and the drawing area doesn't behave differently // whether its fixed or not. We still need to tell the drawing area which part of it @@ -821,7 +825,7 @@ QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* view QQuickWebViewFlickablePrivate::~QQuickWebViewFlickablePrivate() { - interactionEngine->disconnect(); + m_viewportHandler->disconnect(); } void QQuickWebViewFlickablePrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef) @@ -834,8 +838,8 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() { Q_Q(QQuickWebView); - interactionEngine.reset(new QtViewportInteractionEngine(webPageProxy.get(), q, pageView.data())); - pageView->eventHandler()->setViewportInteractionEngine(interactionEngine.data()); + m_viewportHandler.reset(new QtViewportHandler(webPageProxy.get(), q, pageView.data())); + pageView->eventHandler()->setViewportHandler(m_viewportHandler.data()); // Trigger setting of correct visibility flags after everything was allocated and initialized. _q_onVisibleChanged(); @@ -843,20 +847,20 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportAttributes& newAttributes) { - if (interactionEngine) - interactionEngine->viewportAttributesChanged(newAttributes); + if (m_viewportHandler) + m_viewportHandler->viewportAttributesChanged(newAttributes); } void QQuickWebViewFlickablePrivate::updateViewportSize() { - // FIXME: Examine why there is not an interactionEngine here in the beginning. - if (interactionEngine) - interactionEngine->viewportItemSizeChanged(); + // FIXME: Examine why there is not an viewportHandler here in the beginning. + if (m_viewportHandler) + m_viewportHandler->viewportItemSizeChanged(); } void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos) { - interactionEngine->pageContentPositionRequested(pos); + m_viewportHandler->pageContentPositionRequested(pos); } void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize) @@ -864,7 +868,7 @@ void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize) Q_Q(QQuickWebView); pageView->setContentsSize(newSize); // emits contentsSizeChanged() - interactionEngine->pageContentsSizeChanged(newSize, q->boundingRect().size().toSize()); + m_viewportHandler->pageContentsSizeChanged(newSize, q->boundingRect().size().toSize()); } /*! @@ -959,7 +963,13 @@ int QQuickWebViewExperimental::preferredMinimumContentsWidth() const void QQuickWebViewExperimental::setPreferredMinimumContentsWidth(int width) { Q_D(QQuickWebView); - d->webPageProxy->pageGroup()->preferences()->setLayoutFallbackWidth(width); + WebPreferences* webPreferences = d->webPageProxy->pageGroup()->preferences(); + + if (width == webPreferences->layoutFallbackWidth()) + return; + + webPreferences->setLayoutFallbackWidth(width); + emit preferredMinimumContentsWidthChanged(); } void QQuickWebViewExperimental::setFlickableViewportEnabled(bool enable) @@ -1187,12 +1197,12 @@ void QQuickWebViewExperimental::setUserAgent(const QString& userAgent) If the above is used on a device with device pixel ratio of 1.5, it will be scaled down but still provide a better looking image. - */ +*/ double QQuickWebViewExperimental::devicePixelRatio() const { Q_D(const QQuickWebView); - return d->webPageProxy->pageGroup()->preferences()->devicePixelRatio(); + return d->webPageProxy->deviceScaleFactor(); } void QQuickWebViewExperimental::setDevicePixelRatio(double devicePixelRatio) @@ -1201,13 +1211,61 @@ void QQuickWebViewExperimental::setDevicePixelRatio(double devicePixelRatio) if (devicePixelRatio == this->devicePixelRatio()) return; - d->webPageProxy->pageGroup()->preferences()->setDevicePixelRatio(devicePixelRatio); + d->webPageProxy->setCustomDeviceScaleFactor(devicePixelRatio); emit devicePixelRatioChanged(); } /*! \internal + \qmlproperty int WebViewExperimental::deviceWidth + \brief The device width used by the viewport calculations. + + The value used when calculation the viewport, eg. what is used for 'device-width' when + used in the viewport meta tag. If unset (zero or negative width), the width of the + actual viewport is used instead. +*/ + +int QQuickWebViewExperimental::deviceWidth() const +{ + Q_D(const QQuickWebView); + return d->webPageProxy->pageGroup()->preferences()->deviceWidth(); +} + +void QQuickWebViewExperimental::setDeviceWidth(int value) +{ + Q_D(QQuickWebView); + d->webPageProxy->pageGroup()->preferences()->setDeviceWidth(qMax(0, value)); + emit deviceWidthChanged(); +} + +/*! + \internal + + \qmlproperty int WebViewExperimental::deviceHeight + \brief The device width used by the viewport calculations. + + The value used when calculation the viewport, eg. what is used for 'device-height' when + used in the viewport meta tag. If unset (zero or negative height), the height of the + actual viewport is used instead. +*/ + +int QQuickWebViewExperimental::deviceHeight() const +{ + Q_D(const QQuickWebView); + return d->webPageProxy->pageGroup()->preferences()->deviceHeight(); +} + +void QQuickWebViewExperimental::setDeviceHeight(int value) +{ + Q_D(QQuickWebView); + d->webPageProxy->pageGroup()->preferences()->setDeviceHeight(qMax(0, value)); + emit deviceHeightChanged(); +} + +/*! + \internal + \qmlmethod void WebViewExperimental::evaluateJavaScript(string script [, function(result)]) \brief Evaluates the specified JavaScript and, if supplied, calls a function with the result. @@ -1239,6 +1297,11 @@ void QQuickWebViewExperimental::setUserScripts(const QList<QUrl>& userScripts) emit userScriptsChanged(); } +QUrl QQuickWebViewExperimental::remoteInspectorUrl() const +{ + return QUrl(WebInspectorServer::shared().inspectorUrlForPageID(d_ptr->webPageProxy->inspector()->remoteInspectionPageID())); +} + QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QQmlListProperty<QQuickUrlSchemeDelegate>* property, int index) { const QObjectList children = property->object->children(); @@ -1743,6 +1806,10 @@ QPointF QQuickWebView::contentPos() const void QQuickWebView::setContentPos(const QPointF& pos) { Q_D(QQuickWebView); + + if (pos == contentPos()) + return; + d->setContentPos(pos); } diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index deb811f7b..b00e12e4b 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -47,7 +47,7 @@ class PlatformWebView; namespace WebKit { class QtRefCountedNetworkRequestData; -class QtViewportInteractionEngine; +class QtViewportHandler; class QtWebPageLoadClient; class QtWebPagePolicyClient; class QtWebPageUIClient; @@ -214,7 +214,7 @@ private: QQuickWebViewExperimental* m_experimental; friend class QWebKitTest; - friend class WebKit::QtViewportInteractionEngine; + friend class WebKit::QtViewportHandler; friend class WebKit::QtWebPageLoadClient; friend class WebKit::QtWebPagePolicyClient; friend class WebKit::QtWebPageUIClient; @@ -248,9 +248,14 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(bool transparentBackground WRITE setTransparentBackground READ transparentBackground) Q_PROPERTY(bool useDefaultContentItemSize WRITE setUseDefaultContentItemSize READ useDefaultContentItemSize) - Q_PROPERTY(int preferredMinimumContentsWidth WRITE setPreferredMinimumContentsWidth READ preferredMinimumContentsWidth) + + Q_PROPERTY(int preferredMinimumContentsWidth WRITE setPreferredMinimumContentsWidth READ preferredMinimumContentsWidth NOTIFY preferredMinimumContentsWidthChanged) + Q_PROPERTY(int deviceWidth WRITE setDeviceWidth READ deviceWidth NOTIFY deviceWidthChanged) + Q_PROPERTY(int deviceHeight WRITE setDeviceHeight READ deviceHeight NOTIFY deviceHeightChanged) + Q_PROPERTY(double devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged) Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL) + Q_PROPERTY(QQmlComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged) Q_PROPERTY(QQmlComponent* confirmDialog READ confirmDialog WRITE setConfirmDialog NOTIFY confirmDialogChanged) Q_PROPERTY(QQmlComponent* promptDialog READ promptDialog WRITE setPromptDialog NOTIFY promptDialogChanged) @@ -260,12 +265,13 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(QQmlComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged) Q_PROPERTY(QQmlComponent* filePicker READ filePicker WRITE setFilePicker NOTIFY filePickerChanged) Q_PROPERTY(QQmlComponent* databaseQuotaDialog READ databaseQuotaDialog WRITE setDatabaseQuotaDialog NOTIFY databaseQuotaDialogChanged) + Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL) Q_PROPERTY(QWebKitTest* test READ test CONSTANT FINAL) 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_PROPERTY(QUrl remoteInspectorUrl READ remoteInspectorUrl NOTIFY remoteInspectorUrlChanged FINAL) Q_ENUMS(NavigationRequestActionExperimental) public: @@ -296,10 +302,15 @@ public: void setDatabaseQuotaDialog(QQmlComponent*); QString userAgent() const; void setUserAgent(const QString& userAgent); + int deviceWidth() const; + void setDeviceWidth(int); + int deviceHeight() const; + void setDeviceHeight(int); double devicePixelRatio() const; void setDevicePixelRatio(double); QList<QUrl> userScripts() const; void setUserScripts(const QList<QUrl>& userScripts); + QUrl remoteInspectorUrl() const; QWebKitTest* test(); @@ -350,10 +361,14 @@ Q_SIGNALS: void messageReceived(const QVariantMap& message); void proxyAuthenticationDialogChanged(); void userAgentChanged(); + void deviceWidthChanged(); + void deviceHeightChanged(); void devicePixelRatioChanged(); void enterFullScreenRequested(); void exitFullScreenRequested(); void userScriptsChanged(); + void preferredMinimumContentsWidthChanged(); + void remoteInspectorUrlChanged(); 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 3c3cb7e9b..c5535a3c8 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -39,7 +39,7 @@ namespace WebKit { class DownloadProxy; class DrawingAreaProxy; class QtDialogRunner; -class QtViewportInteractionEngine; +class QtViewportHandler; class QtWebContext; class QtWebError; class QtWebPageLoadClient; @@ -89,7 +89,7 @@ public: int loadProgress() const { return m_loadProgress; } void setNeedsDisplay(); - virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return 0; } + virtual WebKit::QtViewportHandler* viewportHandler() { return 0; } virtual void updateViewportSize() { } void updateTouchViewportSize(); @@ -222,14 +222,14 @@ public: virtual void onComponentComplete(); virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&); - virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return interactionEngine.data(); } + virtual WebKit::QtViewportHandler* viewportHandler() { return m_viewportHandler.data(); } virtual void updateViewportSize(); virtual void pageDidRequestScroll(const QPoint& pos); virtual void didChangeContentsSize(const QSize& newSize); private: - QScopedPointer<WebKit::QtViewportInteractionEngine> interactionEngine; + QScopedPointer<WebKit::QtViewportHandler> m_viewportHandler; }; #endif // qquickwebview_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp index 13decd7d0..0930708d4 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp @@ -21,7 +21,7 @@ #include "config.h" #include "qwebkittest_p.h" -#include "QtViewportInteractionEngine.h" +#include "QtViewportHandler.h" #include "qquickwebview_p_p.h" #include "qwindowsysteminterface_qpa.h" #include <QMutableListIterator> @@ -120,49 +120,49 @@ QSize QWebKitTest::contentsSize() const QVariant QWebKitTest::contentsScale() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return viewport->currentCSSScale(); return 1.0; } QVariant QWebKitTest::devicePixelRatio() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return viewport->m_devicePixelRatio; return 1.0; } QVariant QWebKitTest::initialScale() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return viewport->m_rawAttributes.initialScale; return 1.0; } QVariant QWebKitTest::minimumScale() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return viewport->m_minimumScale; return 1.0; } QVariant QWebKitTest::maximumScale() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return viewport->m_maximumScale; return 1.0; } QVariant QWebKitTest::isScalable() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return !!viewport->m_rawAttributes.userScalable; return false; } QVariant QWebKitTest::layoutSize() const { - if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) + if (QtViewportHandler* viewport = m_webViewPrivate->viewportHandler()) return QSizeF(viewport->m_rawAttributes.layoutSize); return QSizeF(); } diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp b/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp index 0b3f36d09..9a30e1fd6 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp @@ -63,6 +63,10 @@ bool QWebPreferencesPrivate::testAttribute(QWebPreferencesPrivate::WebAttribute return WKPreferencesGetFrameFlatteningEnabled(preferencesRef()); case DeveloperExtrasEnabled: return WKPreferencesGetDeveloperExtrasEnabled(preferencesRef()); +#if ENABLE(WEBGL) + case WebGLEnabled: + return WKPreferencesGetWebGLEnabled(preferencesRef()); +#endif default: ASSERT_NOT_REACHED(); return false; @@ -106,6 +110,11 @@ void QWebPreferencesPrivate::setAttribute(QWebPreferencesPrivate::WebAttribute a case DeveloperExtrasEnabled: WKPreferencesSetDeveloperExtrasEnabled(preferencesRef(), enable); break; +#if ENABLE(WEBGL) + case WebGLEnabled: + WKPreferencesSetWebGLEnabled(preferencesRef(), enable); + break; +#endif default: ASSERT_NOT_REACHED(); } @@ -476,6 +485,25 @@ void QWebPreferences::setDefaultFixedFontSize(unsigned size) emit defaultFixedFontSizeChanged(); } +bool QWebPreferences::webGLEnabled() const +{ +#if ENABLE(WEBGL) + return d->testAttribute(QWebPreferencesPrivate::WebGLEnabled); +#else + return false; +#endif +} + +void QWebPreferences::setWebGLEnabled(bool enable) +{ +#if ENABLE(WEBGL) + d->setAttribute(QWebPreferencesPrivate::WebGLEnabled, enable); + emit webGLEnabledChanged(); +#else + UNUSED_PARAM(enable); +#endif +} + WKPreferencesRef QWebPreferencesPrivate::preferencesRef() const { WKPageGroupRef pageGroupRef = toAPI(webViewPrivate->webPageProxy->pageGroup()); diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h index 24859bff2..8618f4fc3 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h @@ -43,6 +43,7 @@ public: Q_PROPERTY(bool navigatorQtObjectEnabled READ navigatorQtObjectEnabled WRITE setNavigatorQtObjectEnabled NOTIFY navigatorQtObjectEnabledChanged FINAL) Q_PROPERTY(bool frameFlatteningEnabled READ frameFlatteningEnabled WRITE setFrameFlatteningEnabled NOTIFY frameFlatteningEnabledChanged FINAL) Q_PROPERTY(bool developerExtrasEnabled READ developerExtrasEnabled WRITE setDeveloperExtrasEnabled NOTIFY developerExtrasEnabledChanged FINAL) + Q_PROPERTY(bool webGLEnabled READ webGLEnabled WRITE setWebGLEnabled NOTIFY webGLEnabledChanged FINAL) Q_PROPERTY(QString standardFontFamily READ standardFontFamily WRITE setStandardFontFamily NOTIFY standardFontFamilyChanged FINAL) Q_PROPERTY(QString fixedFontFamily READ fixedFontFamily WRITE setFixedFontFamily NOTIFY fixedFontFamilyChanged FINAL) @@ -91,6 +92,9 @@ public: bool developerExtrasEnabled() const; void setDeveloperExtrasEnabled(bool enable); + bool webGLEnabled() const; + void setWebGLEnabled(bool enable); + QString standardFontFamily() const; void setStandardFontFamily(const QString& family); @@ -131,6 +135,7 @@ Q_SIGNALS: void navigatorQtObjectEnabledChanged(); void frameFlatteningEnabledChanged(); void developerExtrasEnabledChanged(); + void webGLEnabledChanged(); void standardFontFamilyChanged(); void fixedFontFamilyChanged(); diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h index ae636c1c7..7c1c9bd4f 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h @@ -38,7 +38,8 @@ public: FrameFlatteningEnabled, PrivateBrowsingEnabled, DnsPrefetchEnabled, - DeveloperExtrasEnabled + DeveloperExtrasEnabled, + WebGLEnabled }; enum FontFamily { diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_devicePixelRatio.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_devicePixelRatio.qml new file mode 100644 index 000000000..643c721da --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_devicePixelRatio.qml @@ -0,0 +1,63 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import "../common" + +Item { + TestWebView { + id: webView + property variant lastResult + } + + SignalSpy { + id: resultSpy + target: webView + signalName: "lastResultChanged" + } + + TestCase { + name: "DevicePixelRatio" + + function init() { + resultSpy.clear() + webView.lastResult = null + } + + function test_devicePixelRatio() { + expectFail("", "This currently fails since window.devicePixelRatio doesn't return the updated value.") + + resultSpy.clear() + webView.url = "about:blank" + webView.experimental.devicePixelRatio = 2.0 + verify(webView.waitForLoadSucceeded()) + + webView.experimental.evaluateJavaScript( + "(function() { return window.devicePixelRatio })()", + function(result) { + webView.lastResult = result + }) + + resultSpy.wait() + compare(webView.lastResult, 2.0) + compare(webView.lastResult, webView.experimental.devicePixelRatio) + } + + function test_devicePixelRatioMediaQuery() { + expectFail("", "This currently fails since the devicePixelRatio from the QML API isn't propagated correctly.") + resultSpy.clear() + webView.url = "about:blank" + webView.experimental.devicePixelRatio = 2.0 + verify(webView.waitForLoadSucceeded()) + + webView.experimental.evaluateJavaScript( + "(function() { return window.matchMedia('-webkit-device-pixel-ratio: 2').matches })()", + function(result) { + webView.lastResult = result + }) + + resultSpy.wait() + verify(webView.lastResult) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_multiFileUpload.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_multiFileUpload.qml index 73ea70845..15bb0bf7c 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_multiFileUpload.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_multiFileUpload.qml @@ -13,16 +13,12 @@ TestWebView { property bool selectFile experimental.filePicker: Item { - Timer { - running: true - interval: 1 - onTriggered: { - var selectedFiles = ["filename1", "filename2"] - if (selectFile) - model.accept(selectedFiles) - else - model.reject(); - } + Component.onCompleted: { + var selectedFiles = ["filename1", "filename2"] + if (selectFile) + model.accept(selectedFiles) + else + model.reject(); } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_singleFileUpload.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_singleFileUpload.qml index be1409b7f..6bcd8036b 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_singleFileUpload.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_singleFileUpload.qml @@ -14,20 +14,16 @@ TestWebView { property bool acceptMultiple: false experimental.filePicker: Item { - Timer { - running: true - interval: 1 - onTriggered: { - var selectedFiles = ["filename1", "filename2"] - if (selectFile) { - if (acceptMultiple) - model.accept(selectedFiles) - else - model.accept("acceptedfilename"); - } + Component.onCompleted: { + var selectedFiles = ["filename1", "filename2"] + if (selectFile) { + if (acceptMultiple) + model.accept(selectedFiles) else - model.reject(); + model.accept("acceptedfilename"); } + else + model.reject(); } } diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.h b/Source/WebKit2/UIProcess/DrawingAreaProxy.h index e86ee8cf2..9f1705dd7 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.h +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.h @@ -86,6 +86,8 @@ public: virtual void pageCustomRepresentationChanged() { } virtual void waitForPossibleGeometryUpdate() { } + virtual void colorSpaceDidChange() { } + #if USE(UI_SIDE_COMPOSITING) virtual void updateViewport(); virtual WebCore::IntRect viewportVisibleRect() const { return contentsRect(); } diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp index 0fd295dcc..156267164 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp +++ b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp @@ -134,14 +134,16 @@ void DrawingAreaProxyImpl::layerHostingModeDidChange() void DrawingAreaProxyImpl::visibilityDidChange() { - if (!m_webPageProxy->isViewVisible()) { - // Suspend painting. - m_webPageProxy->process()->send(Messages::DrawingArea::SuspendPainting(), m_webPageProxy->pageID()); - return; - } + if (!m_webPageProxy->suppressVisibilityUpdates()) { + if (!m_webPageProxy->isViewVisible()) { + // Suspend painting. + m_webPageProxy->process()->send(Messages::DrawingArea::SuspendPainting(), m_webPageProxy->pageID()); + return; + } - // Resume painting. - m_webPageProxy->process()->send(Messages::DrawingArea::ResumePainting(), m_webPageProxy->pageID()); + // Resume painting. + m_webPageProxy->process()->send(Messages::DrawingArea::ResumePainting(), m_webPageProxy->pageID()); + } #if USE(ACCELERATED_COMPOSITING) // If we don't have a backing store, go ahead and mark the backing store as being changed so diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp index f335849ed..ecb171bb4 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp @@ -94,6 +94,13 @@ void WebInspectorServer::unregisterPage(int pageId) closeConnection(0, connection); } +#if !PLATFORM(QT) +String WebInspectorServer::inspectorUrlForPageID(int) +{ + return String(); +} +#endif + void WebInspectorServer::sendMessageOverConnection(unsigned pageIdForConnection, const String& message) { WebSocketServerConnection* connection = m_connectionMap.get(pageIdForConnection); diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h index f0bbc213c..a86635ee0 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h +++ b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h @@ -46,6 +46,7 @@ public: // Page registry to manage known pages. int registerPage(WebInspectorProxy* client); void unregisterPage(int pageId); + String inspectorUrlForPageID(int pageId); void sendMessageOverConnection(unsigned pageIdForConnection, const String& message); private: diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp index 1ccdbc8e6..7a0beb5de 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp @@ -45,6 +45,7 @@ namespace WebKit { WebSocketServer::WebSocketServer(WebSocketServerClient* client) : m_state(Closed) , m_client(client) + , m_port(0) { platformInitialize(); } @@ -62,7 +63,11 @@ bool WebSocketServer::listen(const String& bindAddress, unsigned short port) return false; bool isNowListening = platformListen(bindAddress, port); - m_state = isNowListening ? Listening : Closed; + if (isNowListening) { + m_bindAddress = bindAddress; + m_port = port; + m_state = Listening; + } return isNowListening; } @@ -72,6 +77,9 @@ void WebSocketServer::close() return; platformClose(); + + m_port = 0; + m_bindAddress = String(); } void WebSocketServer::didAcceptConnection(PassRefPtr<SocketStreamHandle> socketHandle) diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h index d60820e43..e5bd2fd40 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h +++ b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h @@ -56,6 +56,9 @@ public: // Server operations. bool listen(const String& bindAddress, unsigned short port); + String bindAddress() const { return m_bindAddress; }; + unsigned short port() const { return m_port; }; + ServerState serverState() const { return m_state; }; void close(); void didAcceptConnection(PassRefPtr<WebCore::SocketStreamHandle>); @@ -70,6 +73,8 @@ private: ServerState m_state; Deque<OwnPtr<WebSocketServerConnection> > m_connections; WebSocketServerClient* m_client; + String m_bindAddress; + unsigned short m_port; #if PLATFORM(QT) OwnPtr<QtTcpServerHandler> m_tcpServerHandler; #endif diff --git a/Source/WebKit2/UIProcess/InspectorServer/qt/WebInspectorServerQt.cpp b/Source/WebKit2/UIProcess/InspectorServer/qt/WebInspectorServerQt.cpp index 9f84a656b..55eef25ac 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/qt/WebInspectorServerQt.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/qt/WebInspectorServerQt.cpp @@ -31,6 +31,12 @@ namespace WebKit { +static String remoteInspectorPagePath() +{ + DEFINE_STATIC_LOCAL(String, pagePath, ("/webkit/inspector/inspector.html?page=")); + return pagePath; +} + bool WebInspectorServer::platformResourceForPath(const String& path, Vector<char>& data, String& contentType) { // The page list contains an unformated list of pages that can be inspected with a link to open a session. @@ -56,6 +62,20 @@ bool WebInspectorServer::platformResourceForPath(const String& path, Vector<char return false; } +String WebInspectorServer::inspectorUrlForPageID(int pageId) +{ + if (pageId <= 0 || serverState() == Closed) + return String(); + StringBuilder builder; + builder.append("http://"); + builder.append(bindAddress()); + builder.append(":"); + builder.append(String::number(port())); + builder.append(remoteInspectorPagePath()); + builder.append(String::number(pageId)); + return builder.toString(); +} + void WebInspectorServer::buildPageList(Vector<char>& data, String& contentType) { StringBuilder builder; @@ -71,7 +91,7 @@ void WebInspectorServer::buildPageList(Vector<char>& data, String& contentType) builder.append("\", \"url\": \""); builder.append(webPage->activeURL()); builder.append("\", \"inspectorUrl\": \""); - builder.append("/webkit/inspector/inspector.html?page=" + String::number(it->first)); + builder.append(remoteInspectorPagePath() + String::number(it->first)); builder.append("\" }"); } builder.append(" ]"); diff --git a/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp b/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp index 5f787647f..687f072f6 100644 --- a/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp +++ b/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp @@ -150,9 +150,13 @@ void LayerTreeHostProxy::didChangeScrollPosition(const IntPoint& position) dispatchUpdate(bind(&WebLayerTreeRenderer::didChangeScrollPosition, m_renderer.get(), position)); } +void LayerTreeHostProxy::syncCanvas(uint32_t id, const IntSize& canvasSize, uint32_t graphicsSurfaceToken) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::syncCanvas, m_renderer.get(), id, canvasSize, graphicsSurfaceToken)); +} + void LayerTreeHostProxy::purgeBackingStores() { - m_renderer->setActive(false); m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID()); } diff --git a/Source/WebKit2/UIProcess/LayerTreeHostProxy.h b/Source/WebKit2/UIProcess/LayerTreeHostProxy.h index ac3d3d2b3..7958a5a5d 100644 --- a/Source/WebKit2/UIProcess/LayerTreeHostProxy.h +++ b/Source/WebKit2/UIProcess/LayerTreeHostProxy.h @@ -69,6 +69,7 @@ public: void updateViewport(); void renderNextFrame(); void didChangeScrollPosition(const WebCore::IntPoint& position); + void syncCanvas(uint32_t id, const WebCore::IntSize& canvasSize, uint32_t graphicsSurfaceToken); void purgeBackingStores(); WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); } diff --git a/Source/WebKit2/UIProcess/LayerTreeHostProxy.messages.in b/Source/WebKit2/UIProcess/LayerTreeHostProxy.messages.in index 1cdae0d33..a88b44fd8 100644 --- a/Source/WebKit2/UIProcess/LayerTreeHostProxy.messages.in +++ b/Source/WebKit2/UIProcess/LayerTreeHostProxy.messages.in @@ -33,5 +33,6 @@ messages -> LayerTreeHostProxy { DestroyDirectlyCompositedImage(int64_t key) DidRenderFrame() DidChangeScrollPosition(WebCore::IntPoint position) + SyncCanvas(uint32_t id, WebCore::IntSize canvasSize, uint32_t graphicsSurfaceToken) } #endif diff --git a/Source/WebKit2/UIProcess/PageClient.h b/Source/WebKit2/UIProcess/PageClient.h index 7c815101d..7401fd799 100644 --- a/Source/WebKit2/UIProcess/PageClient.h +++ b/Source/WebKit2/UIProcess/PageClient.h @@ -36,7 +36,10 @@ #if PLATFORM(MAC) #include "PluginComplexTextInputState.h" +#if USE(APPKIT) OBJC_CLASS WKView; +OBJC_CLASS NSTextAlternatives; +#endif #endif namespace WebCore { @@ -63,6 +66,10 @@ class WebPopupMenuProxy; struct WindowGeometry; #endif +#if PLATFORM(MAC) +struct ColorSpaceData; +#endif + class PageClient { public: virtual ~PageClient() { } @@ -190,9 +197,20 @@ public: virtual String dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText) = 0; virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponseType, const String& replacedString, const String& replacementString) = 0; virtual void recommendedScrollbarStyleDidChange(int32_t newStyle) = 0; - + + virtual ColorSpaceData colorSpace() = 0; + +#if USE(APPKIT) virtual WKView* wkView() const = 0; -#endif +#if USE(DICTATION_ALTERNATIVES) + virtual uint64_t addDictationAlternatives(const RetainPtr<NSTextAlternatives>&) = 0; + virtual void removeDictationAlternatives(uint64_t dictationContext) = 0; + virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) = 0; + virtual void dismissDictationAlternativeUI() = 0; + virtual Vector<String> dictationAlternatives(uint64_t dictationContext) = 0; +#endif // USE(DICTATION_ALTERNATIVES) +#endif // USE(APPKIT) +#endif // PLATFORM(MAC) virtual void didChangeScrollbarsForMainFrame() const = 0; diff --git a/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp b/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp index 9b7f2b2dd..b0a5b230d 100644 --- a/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp +++ b/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp @@ -29,12 +29,23 @@ #if ENABLE(PLUGIN_PROCESS) #include "ProcessExecutablePath.h" +#include "QtDefaultDataLocation.h" #include <QByteArray> #include <QCoreApplication> +#include <QDateTime> #include <QDir> #include <QEventLoop> +#include <QFile> +#include <QJsonArray> +#include <QJsonDocument> +#include <QJsonObject> +#include <QMap> #include <QProcess> -#include <QString> +#include <QStringBuilder> +#include <QVariant> +#include <WebCore/FileSystem.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> namespace WebKit { @@ -44,35 +55,181 @@ void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationPa { } +static PassOwnPtr<QFile> cacheFile() +{ + static QString cacheFilePath = defaultDataLocation() % QStringLiteral("plugin_meta_data.json"); + return adoptPtr(new QFile(cacheFilePath)); +} + +struct ReadResult { + enum Tag { + Empty, + Error, + Success + }; +}; + +static ReadResult::Tag readMetaDataFromCacheFile(QJsonDocument& result) +{ + OwnPtr<QFile> file = cacheFile(); + if (!file->open(QFile::ReadOnly)) + return ReadResult::Empty; + QByteArray data = file->readAll(); + if (data.isEmpty()) + return ReadResult::Empty; + + QJsonParseError error; + result = QJsonDocument::fromJson(data, &error); + if (error.error != QJsonParseError::NoError || !result.isArray()) { + // Corrupted file. + file->remove(); + return ReadResult::Error; + } + + return ReadResult::Success; +} + +static void writeToCacheFile(const QJsonArray& array) +{ + OwnPtr<QFile> file = cacheFile(); + if (!file->open(QFile::WriteOnly | QFile::Truncate)) { + // It should never but let's be pessimistic, it is the file system after all. + qWarning("Cannot write into plugin meta data cache file: %s\n", qPrintable(file->fileName())); + return; + } + + // Don't care about write error here. We will detect it later. + file->write(QJsonDocument(array).toJson()); +} + +static void appendToCacheFile(const QJsonObject& object) +{ + QJsonDocument jsonDocument; + ReadResult::Tag result = readMetaDataFromCacheFile(jsonDocument); + if (result == ReadResult::Error) + return; + if (result == ReadResult::Empty) + jsonDocument.setArray(QJsonArray()); + + QJsonArray array = jsonDocument.array(); + array.append(object); + writeToCacheFile(array); +} + +struct MetaDataResult { + enum Tag { + NotAvailable, + Unloadable, + Available + }; +}; + +static MetaDataResult::Tag tryReadPluginMetaDataFromCacheFile(const QString& canonicalPluginPath, RawPluginMetaData& result) +{ + QJsonDocument jsonDocument; + if (readMetaDataFromCacheFile(jsonDocument) != ReadResult::Success) + return MetaDataResult::NotAvailable; + + QJsonArray array = jsonDocument.array(); + QDateTime pluginLastModified = QFileInfo(canonicalPluginPath).lastModified(); + for (QJsonArray::const_iterator i = array.constBegin(); i != array.constEnd(); ++i) { + QJsonValue item = *i; + if (!item.isObject()) { + cacheFile()->remove(); + return MetaDataResult::NotAvailable; + } + + QJsonObject object = item.toObject(); + if (object.value(QStringLiteral("path")).toString() == canonicalPluginPath) { + QString timestampString = object.value(QStringLiteral("timestamp")).toString(); + if (timestampString.isEmpty()) { + cacheFile()->remove(); + return MetaDataResult::NotAvailable; + } + QDateTime timestamp = QDateTime::fromString(timestampString); + if (timestamp < pluginLastModified) { + // Out of date data for this plugin => remove it from the file. + array.removeAt(i.i); + writeToCacheFile(array); + return MetaDataResult::NotAvailable; + } + + if (object.contains(QLatin1String("unloadable"))) + return MetaDataResult::Unloadable; + + // Match. + result.name = object.value(QStringLiteral("name")).toString(); + result.description = object.value(QStringLiteral("description")).toString(); + result.mimeDescription = object.value(QStringLiteral("mimeDescription")).toString(); + if (result.mimeDescription.isEmpty()) { + // Only the mime description is mandatory. + // Don't trust in the cache file if it is empty. + cacheFile()->remove(); + return MetaDataResult::NotAvailable; + } + + return MetaDataResult::Available; + } + } + + return MetaDataResult::NotAvailable; +} + bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result) { - QString commandLine = QLatin1String("%1 %2 %3"); - commandLine = commandLine.arg(executablePathOfPluginProcess()); - commandLine = commandLine.arg(QStringLiteral("-scanPlugin")).arg(static_cast<QString>(pluginPath)); + QFileInfo pluginFileInfo(pluginPath); + if (!pluginFileInfo.exists()) + return false; + + MetaDataResult::Tag metaDataResult = tryReadPluginMetaDataFromCacheFile(pluginFileInfo.canonicalFilePath(), result); + if (metaDataResult == MetaDataResult::Available) + return true; + if (metaDataResult == MetaDataResult::Unloadable) + return false; + // Scan the plugin via the plugin process. + QString commandLine = QString(executablePathOfPluginProcess()) % QLatin1Char(' ') + % QStringLiteral("-scanPlugin") % QLatin1Char(' ') % pluginFileInfo.canonicalFilePath(); QProcess process; process.setReadChannel(QProcess::StandardOutput); process.start(commandLine); - if (!process.waitForFinished() - || process.exitStatus() != QProcess::NormalExit - || process.exitCode() != EXIT_SUCCESS) { + bool ranSuccessfully = process.waitForFinished() + && process.exitStatus() == QProcess::NormalExit + && process.exitCode() == EXIT_SUCCESS; + if (ranSuccessfully) { + QByteArray outputBytes = process.readAll(); + ASSERT(!(outputBytes.size() % sizeof(UChar))); + + String output(reinterpret_cast<const UChar*>(outputBytes.constData()), outputBytes.size() / sizeof(UChar)); + Vector<String> lines; + output.split(UChar('\n'), lines); + ASSERT(lines.size() == 3); + + result.name.swap(lines[0]); + result.description.swap(lines[1]); + result.mimeDescription.swap(lines[2]); + } else process.kill(); - return false; - } - QByteArray outputBytes = process.readAll(); - ASSERT(!(outputBytes.size() % sizeof(UChar))); + QVariantMap map; + map[QStringLiteral("path")] = QString(pluginFileInfo.canonicalFilePath()); + map[QStringLiteral("timestamp")] = QDateTime::currentDateTime().toString(); + + if (!ranSuccessfully || result.mimeDescription.isEmpty()) { + // We failed getting the meta data in some way. Cache this information, so we don't + // need to rescan such plugins every time. We will retry it once the plugin is updated. - String output(reinterpret_cast<const UChar*>(outputBytes.constData()), outputBytes.size() / sizeof(UChar)); - Vector<String> lines; - output.split(UChar('\n'), lines); - ASSERT(lines.size() == 3); + map[QStringLiteral("unloadable")] = QStringLiteral("true"); + appendToCacheFile(QJsonObject::fromVariantMap(map)); + return false; + } - result.name.swap(lines[0]); - result.description.swap(lines[1]); - result.mimeDescription.swap(lines[2]); - return !result.mimeDescription.isEmpty(); + map[QStringLiteral("name")] = QString(result.name); + map[QStringLiteral("description")] = QString(result.description); + map[QStringLiteral("mimeDescription")] = QString(result.mimeDescription); + appendToCacheFile(QJsonObject::fromVariantMap(map)); + return true; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebIconDatabase.cpp b/Source/WebKit2/UIProcess/WebIconDatabase.cpp index 10804f702..c0c70617b 100644 --- a/Source/WebKit2/UIProcess/WebIconDatabase.cpp +++ b/Source/WebKit2/UIProcess/WebIconDatabase.cpp @@ -190,6 +190,14 @@ Image* WebIconDatabase::imageForPageURL(const String& pageURL, const WebCore::In return m_iconDatabaseImpl->synchronousIconForPageURL(pageURL, iconSize); } +WebCore::NativeImagePtr WebIconDatabase::nativeImageForPageURL(const String& pageURL, const WebCore::IntSize& iconSize) +{ + if (!m_webContext || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty()) + return 0; + + return m_iconDatabaseImpl->synchronousNativeIconForPageURL(pageURL, iconSize); +} + bool WebIconDatabase::isOpen() { return m_iconDatabaseImpl && m_iconDatabaseImpl->isOpen(); diff --git a/Source/WebKit2/UIProcess/WebIconDatabase.h b/Source/WebKit2/UIProcess/WebIconDatabase.h index 7ae3fdce0..d808ef0d9 100644 --- a/Source/WebKit2/UIProcess/WebIconDatabase.h +++ b/Source/WebKit2/UIProcess/WebIconDatabase.h @@ -31,6 +31,7 @@ #include "Connection.h" #include "WebIconDatabaseClient.h" #include <WebCore/IconDatabaseClient.h> +#include <WebCore/ImageSource.h> #include <WebCore/IntSize.h> #include <wtf/Forward.h> #include <wtf/PassRefPtr.h> @@ -78,6 +79,7 @@ public: void getLoadDecisionForIconURL(const String&, uint64_t callbackID); WebCore::Image* imageForPageURL(const String&, const WebCore::IntSize& iconSize = WebCore::IntSize(32, 32)); + WebCore::NativeImagePtr nativeImageForPageURL(const String&, const WebCore::IntSize& iconSize = WebCore::IntSize(32, 32)); bool isOpen(); void removeAllIcons(); diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.h b/Source/WebKit2/UIProcess/WebInspectorProxy.h index 02cf52cbc..0958472e8 100644 --- a/Source/WebKit2/UIProcess/WebInspectorProxy.h +++ b/Source/WebKit2/UIProcess/WebInspectorProxy.h @@ -135,6 +135,7 @@ public: void remoteFrontendConnected(); void remoteFrontendDisconnected(); void dispatchMessageFromRemoteFrontend(const String& message); + int remoteInspectionPageID() const { return m_remoteInspectionPageId; } #endif private: diff --git a/Source/WebKit2/UIProcess/WebIntentData.cpp b/Source/WebKit2/UIProcess/WebIntentData.cpp new file mode 100644 index 000000000..37695a4fe --- /dev/null +++ b/Source/WebKit2/UIProcess/WebIntentData.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIntentData.h" + +#if ENABLE(WEB_INTENTS) + +namespace WebKit { + +WebIntentData::WebIntentData(const IntentData& store) + : m_store(store) +{ +} + +PassRefPtr<WebSerializedScriptValue> WebIntentData::data() const +{ + Vector<uint8_t> dataCopy = m_store.data; + return WebSerializedScriptValue::adopt(dataCopy); +} + +} // namespace WebKit + +#endif // ENABLE(WEB_INTENTS) + diff --git a/Source/WebKit2/UIProcess/WebIntentData.h b/Source/WebKit2/UIProcess/WebIntentData.h new file mode 100644 index 000000000..3caef5094 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebIntentData.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIntentData_h +#define WebIntentData_h + +#if ENABLE(WEB_INTENTS) + +#include "APIObject.h" +#include "IntentData.h" +#include "WebSerializedScriptValue.h" +#include <wtf/PassRefPtr.h> + +namespace WebKit { + +class WebIntentData : public APIObject { +public: + static const Type APIType = TypeIntentData; + + static PassRefPtr<WebIntentData> create(const IntentData& store) + { + return adoptRef(new WebIntentData(store)); + } + + virtual ~WebIntentData() { } + + const String& action() const { return m_store.action; } + const String& payloadType() const { return m_store.type; } + const WebCore::KURL& service() const { return m_store.service; } + PassRefPtr<WebSerializedScriptValue> data() const; + const HashMap<String, String>& extras() const { return m_store.extras; } + const Vector<WebCore::KURL>& suggestions() const { return m_store.suggestions; } + +private: + WebIntentData(const IntentData&); + + virtual Type type() const { return APIType; } + + IntentData m_store; +}; + +} // namespace WebKit + +#endif // ENABLE(WEB_INTENTS) + +#endif // WebIntentData_h diff --git a/Source/WebKit2/UIProcess/WebIntentServiceInfo.cpp b/Source/WebKit2/UIProcess/WebIntentServiceInfo.cpp new file mode 100644 index 000000000..84329c5e7 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebIntentServiceInfo.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIntentServiceInfo.h" + +#if ENABLE(WEB_INTENTS_TAG) + +namespace WebKit { + +WebIntentServiceInfo::WebIntentServiceInfo(const IntentServiceInfo& store) + : m_store(store) +{ +} + +} // namespace WebKit + +#endif // ENABLE(WEB_INTENTS_TAG) diff --git a/Source/WebKit2/UIProcess/WebIntentServiceInfo.h b/Source/WebKit2/UIProcess/WebIntentServiceInfo.h new file mode 100644 index 000000000..8694601f0 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebIntentServiceInfo.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIntentServiceInfo_h +#define WebIntentServiceInfo_h + +#if ENABLE(WEB_INTENTS_TAG) + +#include "APIObject.h" +#include "IntentServiceInfo.h" +#include <wtf/PassRefPtr.h> + +namespace WebKit { + +class WebIntentServiceInfo : public APIObject { +public: + static const Type APIType = TypeIntentServiceInfo; + + static PassRefPtr<WebIntentServiceInfo> create(const IntentServiceInfo& store) + { + return adoptRef(new WebIntentServiceInfo(store)); + } + + virtual ~WebIntentServiceInfo() { } + + const String& action() const { return m_store.action; } + const String& payloadType() const { return m_store.type; } + const WebCore::KURL& href() const { return m_store.href; } + const String& title() const { return m_store.title; } + const String& disposition() const { return m_store.disposition; } + +private: + WebIntentServiceInfo(const IntentServiceInfo&); + + virtual Type type() const { return APIType; } + + IntentServiceInfo m_store; +}; + +} // namespace WebKit + +#endif // ENABLE(WEB_INTENTS_TAG) + +#endif // WebIntentServiceInfo_h diff --git a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp index c6c0fadf8..c3e573923 100644 --- a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp +++ b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp @@ -30,6 +30,7 @@ #include "ShareableBitmap.h" #include "TextureMapper.h" #include "TextureMapperBackingStore.h" +#include "TextureMapperGL.h" #include "TextureMapperLayer.h" #include "UpdateInfo.h" #include <OpenGLShims.h> @@ -85,7 +86,8 @@ static IntPoint boundedScrollPosition(const IntPoint& scrollPosition, const IntR } WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeHostProxy* layerTreeHostProxy) - : m_layerTreeHostProxy(layerTreeHostProxy) + : m_contentsScale(1) + , m_layerTreeHostProxy(layerTreeHostProxy) , m_rootLayerID(InvalidWebLayerID) , m_isActive(false) { @@ -194,6 +196,28 @@ void WebLayerTreeRenderer::didChangeScrollPosition(const IntPoint& position) m_pendingRenderedContentsScrollPosition = boundedScrollPosition(position, m_visibleContentsRect, m_contentsSize); } +void WebLayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint32_t graphicsSurfaceToken) +{ + if (canvasSize.isEmpty() || !m_textureMapper) + return; + +#if USE(GRAPHICS_SURFACE) + ensureLayer(id); + GraphicsLayer* layer = layerByID(id); + + RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore; + SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(id); + if (it == m_surfaceBackingStores.end()) { + canvasBackingStore = TextureMapperSurfaceBackingStore::create(); + m_surfaceBackingStores.set(id, canvasBackingStore); + } else + canvasBackingStore = it->second; + + canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize); + layer->setContentsToMedia(canvasBackingStore.get()); +#endif +} + void WebLayerTreeRenderer::setLayerChildren(WebLayerID id, const Vector<WebLayerID>& childIDs) { ensureLayer(id); @@ -271,6 +295,9 @@ void WebLayerTreeRenderer::deleteLayer(WebLayerID layerID) layer->removeFromParent(); m_layers.remove(layerID); m_fixedLayers.remove(layerID); +#if USE(GRAPHICS_SURFACE) + m_surfaceBackingStores.remove(layerID); +#endif delete layer; } @@ -419,6 +446,9 @@ void WebLayerTreeRenderer::purgeGLResources() layer->clearBackingStoresRecursive(); m_directlyCompositedImages.clear(); +#if USE(GRAPHICS_SURFACE) + m_surfaceBackingStores.clear(); +#endif m_rootLayer->removeAllChildren(); m_rootLayer.clear(); @@ -428,6 +458,8 @@ void WebLayerTreeRenderer::purgeGLResources() m_textureMapper.clear(); m_backingStoresWithPendingBuffers.clear(); + setActive(false); + callOnMainThread(bind(&WebLayerTreeRenderer::purgeBackingStores, this)); } diff --git a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h index 042c52d06..d66b19d63 100644 --- a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h +++ b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h @@ -22,6 +22,7 @@ #if USE(UI_SIDE_COMPOSITING) #include "BackingStore.h" +#include "GraphicsSurface.h" #include "ShareableSurface.h" #include "TextureMapper.h" #include "TextureMapperBackingStore.h" @@ -67,6 +68,7 @@ public: void setContentsSize(const WebCore::FloatSize&); void setVisibleContentsRect(const WebCore::IntRect&, float scale, const WebCore::FloatPoint& accurateVisibleContentsPosition); void didChangeScrollPosition(const WebCore::IntPoint& position); + void syncCanvas(uint32_t id, const WebCore::IntSize& canvasSize, uint32_t graphicsSurfaceToken); void detach(); void appendUpdate(const Function<void()>&); @@ -118,6 +120,10 @@ private: HashMap<int64_t, RefPtr<WebCore::TextureMapperBackingStore> > m_directlyCompositedImages; HashSet<RefPtr<LayerBackingStore> > m_backingStoresWithPendingBuffers; #endif +#if USE(GRAPHICS_SURFACE) + typedef HashMap<WebLayerID, RefPtr<WebCore::TextureMapperSurfaceBackingStore> > SurfaceBackingStoreMap; + SurfaceBackingStoreMap m_surfaceBackingStores; +#endif void scheduleWebViewUpdate(); void synchronizeViewport(); diff --git a/Source/WebKit2/UIProcess/WebLoaderClient.cpp b/Source/WebKit2/UIProcess/WebLoaderClient.cpp index 92750124e..289e8797d 100644 --- a/Source/WebKit2/UIProcess/WebLoaderClient.cpp +++ b/Source/WebKit2/UIProcess/WebLoaderClient.cpp @@ -27,10 +27,15 @@ #include "WebLoaderClient.h" #include "ImmutableArray.h" -#include "WebBackForwardListItem.h" #include "WKAPICast.h" +#include "WebBackForwardListItem.h" #include <string.h> +#if ENABLE(WEB_INTENTS) +#include "WebIntentData.h" +#include "WebIntentServiceInfo.h" +#endif + using namespace WebCore; namespace WebKit { @@ -163,6 +168,26 @@ void WebLoaderClient::didDetectXSSForFrame(WebPageProxy* page, WebFrameProxy* fr m_client.didDetectXSSForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo); } +#if ENABLE(WEB_INTENTS) +void WebLoaderClient::didReceiveIntentForFrame(WebPageProxy* page, WebFrameProxy* frame, WebIntentData* intentData) +{ + if (!m_client.didReceiveIntentForFrame) + return; + + m_client.didReceiveIntentForFrame(toAPI(page), toAPI(frame), toAPI(intentData), m_client.clientInfo); +} +#endif + +#if ENABLE(WEB_INTENTS_TAG) +void WebLoaderClient::registerIntentServiceForFrame(WebPageProxy* page, WebFrameProxy* frame, WebIntentServiceInfo* serviceInfo) +{ + if (!m_client.registerIntentServiceForFrame) + return; + + m_client.registerIntentServiceForFrame(toAPI(page), toAPI(frame), toAPI(serviceInfo), m_client.clientInfo); +} +#endif + bool WebLoaderClient::canAuthenticateAgainstProtectionSpaceInFrame(WebPageProxy* page, WebFrameProxy* frame, WebProtectionSpace* protectionSpace) { if (!m_client.canAuthenticateAgainstProtectionSpaceInFrame) diff --git a/Source/WebKit2/UIProcess/WebLoaderClient.h b/Source/WebKit2/UIProcess/WebLoaderClient.h index 8cf687b97..f8e44c74f 100644 --- a/Source/WebKit2/UIProcess/WebLoaderClient.h +++ b/Source/WebKit2/UIProcess/WebLoaderClient.h @@ -47,6 +47,14 @@ class WebFrameProxy; class WebPageProxy; class WebProtectionSpace; +#if ENABLE(WEB_INTENTS) +class WebIntentData; +#endif + +#if ENABLE(WEB_INTENTS_TAG) +class WebIntentServiceInfo; +#endif + class WebLoaderClient : public APIClient<WKPageLoaderClient, kWKPageLoaderClientCurrentVersion> { public: void didStartProvisionalLoadForFrame(WebPageProxy*, WebFrameProxy*, APIObject*); @@ -64,6 +72,13 @@ public: void didDisplayInsecureContentForFrame(WebPageProxy*, WebFrameProxy*, APIObject*); void didRunInsecureContentForFrame(WebPageProxy*, WebFrameProxy*, APIObject*); void didDetectXSSForFrame(WebPageProxy*, WebFrameProxy*, APIObject*); +#if ENABLE(WEB_INTENTS) + void didReceiveIntentForFrame(WebPageProxy*, WebFrameProxy*, WebIntentData*); +#endif + +#if ENABLE(WEB_INTENTS_TAG) + void registerIntentServiceForFrame(WebPageProxy*, WebFrameProxy*, WebIntentServiceInfo*); +#endif // FIXME: didFirstVisuallyNonEmptyLayoutForFrame and didNewFirstVisuallyNonEmptyLayout should be merged. // The only reason for both to exist is to experiment with different heuristics for the time being. diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp index 2b538e5d8..16d4a981d 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp @@ -85,6 +85,13 @@ #include <WebCore/WindowFeatures.h> #include <stdio.h> +#if ENABLE(WEB_INTENTS) +#include "IntentData.h" +#include "IntentServiceInfo.h" +#include "WebIntentData.h" +#include "WebIntentServiceInfo.h" +#endif + #if USE(UI_SIDE_COMPOSITING) #include "LayerTreeHostProxyMessages.h" #endif @@ -210,6 +217,7 @@ WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr<WebProcessProxy> p , m_pageCount(0) , m_renderTreeSize(0) , m_shouldSendEventsSynchronously(false) + , m_suppressVisibilityUpdates(false) , m_mediaVolume(1) #if ENABLE(PAGE_VISIBILITY_API) , m_visibilityState(PageVisibilityStateVisible) @@ -1866,6 +1874,17 @@ void WebPageProxy::didFinishProgress() m_loaderClient.didFinishProgress(this); } +#if ENABLE(WEB_INTENTS_TAG) +void WebPageProxy::registerIntentServiceForFrame(uint64_t frameID, const IntentServiceInfo& serviceInfo) +{ + WebFrameProxy* frame = process()->webFrame(frameID); + MESSAGE_CHECK(frame); + + RefPtr<WebIntentServiceInfo> webIntentServiceInfo = WebIntentServiceInfo::create(serviceInfo); + m_loaderClient.registerIntentServiceForFrame(this, frame, webIntentServiceInfo.get()); +} +#endif + void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, CoreIPC::ArgumentDecoder* arguments) { clearPendingAPIRequestURL(); @@ -2136,6 +2155,17 @@ void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, CoreIPC::ArgumentDecod m_loaderClient.didDetectXSSForFrame(this, frame, userData.get()); } +#if ENABLE(WEB_INTENTS) +void WebPageProxy::didReceiveIntentForFrame(uint64_t frameID, const IntentData& intentData) +{ + WebFrameProxy* frame = process()->webFrame(frameID); + MESSAGE_CHECK(frame); + + RefPtr<WebIntentData> webIntentData = WebIntentData::create(intentData); + m_loaderClient.didReceiveIntentForFrame(this, frame, webIntentData.get()); +} +#endif + void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value) { WebFrameProxy* frame = process()->webFrame(frameID); @@ -3468,6 +3498,7 @@ WebPageCreationParameters WebPageProxy::creationParameters() const #if PLATFORM(MAC) parameters.isSmartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled; parameters.layerHostingMode = m_layerHostingMode; + parameters.colorSpace = m_pageClient->colorSpace(); #endif #if PLATFORM(WIN) @@ -3810,6 +3841,29 @@ void WebPageProxy::handleAlternativeTextUIResult(const String& result) process()->send(Messages::WebPage::HandleAlternativeTextUIResult(result), m_pageID, 0); #endif } + +#if USE(DICTATION_ALTERNATIVES) +void WebPageProxy::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) +{ + m_pageClient->showDictationAlternativeUI(boundingBoxOfDictatedText, dictationContext); +} + +void WebPageProxy::dismissDictationAlternativeUI() +{ + m_pageClient->dismissDictationAlternativeUI(); +} + +void WebPageProxy::removeDictationAlternatives(uint64_t dictationContext) +{ + m_pageClient->removeDictationAlternatives(dictationContext); +} + +void WebPageProxy::dictationAlternatives(uint64_t dictationContext, Vector<String>& result) +{ + result = m_pageClient->dictationAlternatives(dictationContext); +} +#endif + #endif // PLATFORM(MAC) } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 95e6c1339..599bcc47f 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -58,6 +58,9 @@ #include "WebPopupMenuProxy.h" #include "WebResourceLoadClient.h" #include "WebUIClient.h" +#include <WebCore/AlternativeTextClient.h> +#include <WebCore/DragActions.h> +#include <WebCore/DragSession.h> #include <WebCore/HitTestResult.h> #include <WebCore/Page.h> #include <WebCore/PlatformScreen.h> @@ -95,6 +98,7 @@ namespace WebCore { class IntSize; class ProtectionSpace; struct FileChooserSettings; + struct TextAlternativeWithRange; struct TextCheckingResult; struct ViewportAttributes; struct WindowFeatures; @@ -104,7 +108,7 @@ namespace WebCore { class QQuickNetworkReply; #endif -#if PLATFORM(MAC) +#if USE(APPKIT) #ifdef __OBJC__ @class WKView; #else @@ -140,6 +144,7 @@ class WebProcessProxy; class WebURLRequest; class WebWheelEvent; struct AttributedString; +struct ColorSpaceData; struct DictionaryPopupInfo; struct EditorState; struct PlatformPopupMenuData; @@ -155,6 +160,14 @@ struct WindowGeometry; class WebGestureEvent; #endif +#if ENABLE(WEB_INTENTS) +struct IntentData; +#endif + +#if ENABLE(WEB_INTENTS_TAG) +struct IntentServiceInfo; +#endif + typedef GenericCallback<WKStringRef, StringImpl*> StringCallback; typedef GenericCallback<WKSerializedScriptValueRef, WebSerializedScriptValue*> ScriptValueCallback; @@ -352,6 +365,7 @@ public: void confirmComposition(); void cancelComposition(); bool insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); + bool insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<WebCore::TextAlternativeWithRange>& dictationAlternatives); void getMarkedRange(uint64_t& location, uint64_t& length); void getSelectedRange(uint64_t& location, uint64_t& length); void getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString&); @@ -364,8 +378,10 @@ public: bool shouldDelayWindowOrderingForEvent(const WebMouseEvent&); bool acceptsFirstMouse(int eventNumber, const WebMouseEvent&); +#if USE(APPKIT) WKView* wkView() const; #endif +#endif #if PLATFORM(WIN) void didChangeCompositionSelection(bool); void confirmComposition(const String&); @@ -477,6 +493,8 @@ public: String stringSelectionForPasteboard(); PassRefPtr<WebCore::SharedBuffer> dataSelectionForPasteboard(const String& pasteboardType); void makeFirstResponder(); + + ColorSpaceData colorSpace(); #endif void pageScaleFactorDidChange(double); @@ -604,11 +622,13 @@ public: void advanceToNextMisspelling(bool startBeforeSelection) const; void changeSpellingToWord(const String& word) const; -#if PLATFORM(MAC) +#if USE(APPKIT) void uppercaseWord(); void lowercaseWord(); void capitalizeWord(); +#endif +#if PLATFORM(MAC) bool isSmartInsertDeleteEnabled() const { return m_isSmartInsertDeleteEnabled; } void setSmartInsertDeleteEnabled(bool); #endif @@ -661,6 +681,13 @@ public: // WebPopupMenuProxy::Client virtual NativeWebMouseEvent* currentlyProcessedMouseDownEvent(); +#if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL) + void widgetMapped(uint64_t nativeWindowId); +#endif + + void setSuppressVisibilityUpdates(bool flag) { m_suppressVisibilityUpdates = flag; } + bool suppressVisibilityUpdates() { return m_suppressVisibilityUpdates; } + private: WebPageProxy(PageClient*, PassRefPtr<WebProcessProxy>, WebPageGroup*, uint64_t pageID); @@ -702,6 +729,13 @@ private: void didStartProgress(); void didChangeProgress(double); void didFinishProgress(); + +#if ENABLE(WEB_INTENTS) + void didReceiveIntentForFrame(uint64_t frameID, const IntentData&); +#endif +#if ENABLE(WEB_INTENTS_TAG) + void registerIntentServiceForFrame(uint64_t frameID, const IntentServiceInfo&); +#endif void decidePolicyForNavigationAction(uint64_t frameID, uint32_t navigationType, uint32_t modifiers, int32_t mouseButton, const WebCore::ResourceRequest&, uint64_t listenerID, CoreIPC::ArgumentDecoder*, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID); void decidePolicyForNewWindowAction(uint64_t frameID, uint32_t navigationType, uint32_t modifiers, int32_t mouseButton, const WebCore::ResourceRequest&, const String& frameName, uint64_t listenerID, CoreIPC::ArgumentDecoder*); @@ -895,6 +929,13 @@ private: void dismissCorrectionPanelSoon(int32_t reason, String& result); void recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString); #endif // !defined(BUILDING_ON_SNOW_LEOPARD) + +#if USE(DICTATION_ALTERNATIVES) + void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext); + void dismissDictationAlternativeUI(); + void removeDictationAlternatives(uint64_t dictationContext); + void dictationAlternatives(uint64_t dictationContext, Vector<String>& result); +#endif #endif // PLATFORM(MAC) void clearLoadDependentCallbacks(); @@ -1091,7 +1132,9 @@ private: static WKPageDebugPaintFlags s_debugPaintFlags; bool m_shouldSendEventsSynchronously; - + + bool m_suppressVisibilityUpdates; + float m_mediaVolume; #if PLATFORM(QT) diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in index de60a7166..06b372f08 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in @@ -89,6 +89,14 @@ messages -> WebPageProxy { DecidePolicyForNewWindowAction(uint64_t frameID, uint32_t navigationType, uint32_t modifiers, int32_t mouseButton, WebCore::ResourceRequest request, WTF::String frameName, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData) + # Intent messages +#if ENABLE(WEB_INTENTS) + DidReceiveIntentForFrame(uint64_t frameID, WebKit::IntentData intent) +#endif +#if ENABLE(WEB_INTENTS_TAG) + RegisterIntentServiceForFrame(uint64_t frameID, WebKit::IntentServiceInfo serviceInfo); +#endif + # Progress messages DidChangeProgress(double value) DidFinishProgress() @@ -281,6 +289,13 @@ messages -> WebPageProxy { RecordAutocorrectionResponse(int32_t responseType, String replacedString, String replacementString); #endif +#if USE(DICTATION_ALTERNATIVES) + ShowDictationAlternativeUI(WebCore::FloatRect boundingBoxOfDictatedText, uint64_t dictationContext) + DismissDictationAlternativeUI() + RemoveDictationAlternatives(uint64_t dictationContext) + DictationAlternatives(uint64_t dictationContext) -> (Vector<String> alternatives) +#endif + #if PLATFORM(WIN) # Windows 7 Gesture Messages SetGestureReachedScrollingLimit(bool limitReached) diff --git a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp index d85b3dda2..d80f24ce7 100644 --- a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp @@ -26,10 +26,12 @@ #include "config.h" #include "WebContextMenuProxyGtk.h" +#if ENABLE(CONTEXT_MENUS) + #include "NativeWebMouseEvent.h" #include "WebContextMenuItemData.h" +#include "WebKitWebViewBasePrivate.h" #include "WebPageProxy.h" -#include <WebCore/ContextMenu.h> #include <WebCore/GtkUtilities.h> #include <gtk/gtk.h> #include <wtf/text/CString.h> @@ -51,59 +53,64 @@ static void contextMenuItemActivatedCallback(GtkAction* action, WebPageProxy* pa page->contextMenuItemSelected(item); } -GtkMenu* WebContextMenuProxyGtk::createGtkMenu(const Vector<WebContextMenuItemData>& items) +void WebContextMenuProxyGtk::append(ContextMenuItem& menuItem) +{ + GtkAction* action = menuItem.gtkAction(); + + if (action && (menuItem.type() == ActionType || menuItem.type() == CheckableActionType)) { + g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action())); + g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page); + } + + m_menu.appendItem(menuItem); +} + +void WebContextMenuProxyGtk::populate(Vector<ContextMenuItem>& items) +{ + for (size_t i = 0; i < items.size(); i++) + append(items.at(i)); +} + +void WebContextMenuProxyGtk::populate(const Vector<WebContextMenuItemData>& items) { - ContextMenu menu; for (size_t i = 0; i < items.size(); i++) { - const WebContextMenuItemData& item = items.at(i); - ContextMenuItem menuItem(item.type(), item.action(), item.title(), item.enabled(), item.checked()); - GtkAction* action = menuItem.gtkAction(); - - if (action && (item.type() == WebCore::ActionType || item.type() == WebCore::CheckableActionType)) { - g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(item.action())); - g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page); - } - - if (item.type() == WebCore::SubmenuType) { - ContextMenu subMenu(createGtkMenu(item.submenu())); - menuItem.setSubMenu(&subMenu); - } - menu.appendItem(menuItem); + ContextMenuItem menuitem = items.at(i).core(); + append(menuitem); } - return menu.releasePlatformDescription(); } void WebContextMenuProxyGtk::showContextMenu(const WebCore::IntPoint& position, const Vector<WebContextMenuItemData>& items) { - if (items.isEmpty()) + if (!items.isEmpty()) + populate(items); + + if (!m_menu.itemCount()) return; - m_popup = createGtkMenu(items); m_popupPosition = convertWidgetPointToScreenPoint(m_webView, position); // Display menu initiated by right click (mouse button pressed = 3). NativeWebMouseEvent* mouseEvent = m_page->currentlyProcessedMouseDownEvent(); const GdkEvent* event = mouseEvent ? mouseEvent->nativeEvent() : 0; - gtk_menu_popup(m_popup, 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, + gtk_menu_popup(m_menu.platformDescription(), 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, event ? event->button.button : 3, event ? event->button.time : GDK_CURRENT_TIME); } void WebContextMenuProxyGtk::hideContextMenu() { - gtk_menu_popdown(m_popup); + gtk_menu_popdown(m_menu.platformDescription()); } WebContextMenuProxyGtk::WebContextMenuProxyGtk(GtkWidget* webView, WebPageProxy* page) : m_webView(webView) , m_page(page) - , m_popup(0) { + webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), this); } WebContextMenuProxyGtk::~WebContextMenuProxyGtk() { - if (m_popup) - gtk_widget_destroy(GTK_WIDGET(m_popup)); + webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), 0); } void WebContextMenuProxyGtk::menuPositionFunction(GtkMenu* menu, gint* x, gint* y, gboolean* pushIn, WebContextMenuProxyGtk* popupMenu) @@ -124,3 +131,4 @@ void WebContextMenuProxyGtk::menuPositionFunction(GtkMenu* menu, gint* x, gint* } } // namespace WebKit +#endif // ENABLE(CONTEXT_MENUS) diff --git a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h index b6a95778b..8e187166e 100644 --- a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h +++ b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h @@ -26,7 +26,10 @@ #ifndef WebContextMenuProxyGtk_h #define WebContextMenuProxyGtk_h +#if ENABLE(CONTEXT_MENUS) + #include "WebContextMenuProxy.h" +#include <WebCore/ContextMenu.h> #include <WebCore/IntPoint.h> namespace WebKit { @@ -45,19 +48,23 @@ public: virtual void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&); virtual void hideContextMenu(); + void populate(Vector<WebCore::ContextMenuItem>&); + private: WebContextMenuProxyGtk(GtkWidget*, WebPageProxy*); - GtkMenu* createGtkMenu(const Vector<WebContextMenuItemData>&); + void append(WebCore::ContextMenuItem&); + void populate(const Vector<WebContextMenuItemData>&); static void menuPositionFunction(GtkMenu*, gint*, gint*, gboolean*, WebContextMenuProxyGtk*); GtkWidget* m_webView; WebPageProxy* m_page; - GtkMenu* m_popup; + WebCore::ContextMenu m_menu; WebCore::IntPoint m_popupPosition; }; } // namespace WebKit +#endif // ENABLE(CONTEXT_MENUS) #endif // WebContextMenuProxyGtk_h diff --git a/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp index dc8235210..ac26c0cb8 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp @@ -31,6 +31,8 @@ #include "NotImplemented.h" #include "PageClientImpl.h" #include "WebKitWebViewBasePrivate.h" +#include "WebPageMessages.h" +#include "WebProcessProxy.h" #include <gtk/gtkx.h> namespace WebKit { @@ -107,4 +109,11 @@ void WebPageProxy::windowedPluginGeometryDidChange(const WebCore::IntRect& frame webkitWebViewBaseChildMoveResize(WEBKIT_WEB_VIEW_BASE(viewWidget()), plugin, frameRect); } +#if USE(TEXTURE_MAPPER_GL) +void WebPageProxy::widgetMapped(uint64_t nativeWindowId) +{ + process()->send(Messages::WebPage::WidgetMapped(nativeWindowId), m_pageID); +} +#endif + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/CorrectionPanel.h b/Source/WebKit2/UIProcess/mac/CorrectionPanel.h index 9fcfcca4c..4c4c34a57 100644 --- a/Source/WebKit2/UIProcess/mac/CorrectionPanel.h +++ b/Source/WebKit2/UIProcess/mac/CorrectionPanel.h @@ -26,12 +26,14 @@ #ifndef CorrectionPanel_h #define CorrectionPanel_h +#import <WebCore/TextChecking.h> + +#if USE(AUTOCORRECTION_PANEL) + #import <AppKit/NSSpellChecker.h> #import <WebCore/AlternativeTextClient.h> #import <wtf/RetainPtr.h> -#if USE(AUTOCORRECTION_PANEL) - @class WKView; namespace WebKit { diff --git a/Source/WebKit2/UIProcess/mac/CorrectionPanel.mm b/Source/WebKit2/UIProcess/mac/CorrectionPanel.mm index 94171f737..33f3fe982 100644 --- a/Source/WebKit2/UIProcess/mac/CorrectionPanel.mm +++ b/Source/WebKit2/UIProcess/mac/CorrectionPanel.mm @@ -26,7 +26,8 @@ #import "config.h" #import "CorrectionPanel.h" -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if USE(AUTOCORRECTION_PANEL) + #import "WebPageProxy.h" #import "WKView.h" #import "WKViewInternal.h" @@ -42,6 +43,9 @@ static inline NSCorrectionIndicatorType correctionIndicatorType(AlternativeTextT return NSCorrectionIndicatorTypeReversion; case AlternativeTextTypeSpellingSuggestions: return NSCorrectionIndicatorTypeGuesses; + case AlternativeTextTypeDictationAlternatives: + ASSERT_NOT_REACHED(); + break; } ASSERT_NOT_REACHED(); return NSCorrectionIndicatorTypeDefault; @@ -137,7 +141,7 @@ void CorrectionPanel::handleAcceptedReplacement(NSString* acceptedReplacement, N break; } - [m_view.get() handleCorrectionPanelResult:acceptedReplacement]; + [m_view.get() handleAcceptedAlternativeText:acceptedReplacement]; m_view.clear(); if (acceptedReplacement) m_resultForDismissal.adoptNS([acceptedReplacement copy]); @@ -145,5 +149,4 @@ void CorrectionPanel::handleAcceptedReplacement(NSString* acceptedReplacement, N } // namespace WebKit -#endif // !defined(BUILDING_ON_SNOW_LEOPARD) - +#endif // USE(AUTOCORRECTION_PANEL) diff --git a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h index c5b6f0e91..08b16508d 100644 --- a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h +++ b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h @@ -47,6 +47,7 @@ private: virtual void visibilityDidChange() OVERRIDE; virtual void sizeDidChange() OVERRIDE; virtual void waitForPossibleGeometryUpdate() OVERRIDE; + virtual void colorSpaceDidChange() OVERRIDE; virtual void enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) OVERRIDE; virtual void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) OVERRIDE; diff --git a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm index 747ed1103..a0c181768 100644 --- a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm +++ b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm @@ -28,6 +28,7 @@ #if ENABLE(THREADED_SCROLLING) +#import "ColorSpaceData.h" #import "DrawingAreaMessages.h" #import "DrawingAreaProxyMessages.h" #import "LayerTreeContext.h" @@ -97,6 +98,11 @@ void TiledCoreAnimationDrawingAreaProxy::waitForPossibleGeometryUpdate() m_webPageProxy->process()->connection()->waitForAndDispatchImmediately<Messages::DrawingAreaProxy::DidUpdateGeometry>(m_webPageProxy->pageID(), didUpdateBackingStoreStateTimeout); } +void TiledCoreAnimationDrawingAreaProxy::colorSpaceDidChange() +{ + m_webPageProxy->process()->send(Messages::DrawingArea::SetColorSpace(m_webPageProxy->colorSpace()), m_webPageProxy->pageID()); +} + void TiledCoreAnimationDrawingAreaProxy::enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) { m_webPageProxy->enterAcceleratedCompositingMode(layerTreeContext); diff --git a/Source/WebKit2/UIProcess/mac/WKFullKeyboardAccessWatcher.h b/Source/WebKit2/UIProcess/mac/WKFullKeyboardAccessWatcher.h index 8b9e81dbc..72e7dbe0a 100644 --- a/Source/WebKit2/UIProcess/mac/WKFullKeyboardAccessWatcher.h +++ b/Source/WebKit2/UIProcess/mac/WKFullKeyboardAccessWatcher.h @@ -26,8 +26,6 @@ #ifndef WKFullKeyboardAccessWatcher_h #define WKFullKeyboardAccessWatcher_h -#import <Cocoa/Cocoa.h> - @interface WKFullKeyboardAccessWatcher : NSObject { @private BOOL fullKeyboardAccessEnabled; diff --git a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm index 68e2cd314..e9579ab9e 100644 --- a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm +++ b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm @@ -55,7 +55,7 @@ static const NSTimeInterval DefaultWatchdogTimerInterval = 1; @interface WKFullScreenWindowController(Private)<NSAnimationDelegate> - (void)_updateMenuAndDockForFullScreen; -- (void)_swapView:(NSView*)view with:(NSView*)otherView; +- (void)_replaceView:(NSView*)view with:(NSView*)otherView; - (WebPageProxy*)_page; - (WebFullScreenManagerProxy*)_manager; - (void)_startEnterFullScreenAnimationWithDuration:(NSTimeInterval)duration; @@ -231,13 +231,19 @@ static RetainPtr<CGImageRef> createImageWithCopiedData(CGImageRef sourceImage) // future overhead. webViewContents = createImageWithCopiedData(webViewContents.get()); - // Screen updates to be re-enabled in beganEnterFullScreenWithInitialFrame:finalFrame: + // Screen updates to be re-enabled in _startEnterFullScreenAnimationWithDuration: NSDisableScreenUpdates(); [[self window] setAutodisplay:NO]; NSResponder *webWindowFirstResponder = [[_webView window] firstResponder]; [[self window] setFrame:screenFrame display:NO]; + // Painting is normally suspended when the WKView is removed from the window, but this is + // unnecessary in the full-screen animation case, and can cause bugs; see + // https://bugs.webkit.org/show_bug.cgi?id=88940 and https://bugs.webkit.org/show_bug.cgi?id=88374 + // We will resume the normal behavior in _startEnterFullScreenAnimationWithDuration: + [_webView _setSuppressVisibilityUpdates:YES]; + // Swap the webView placeholder into place. if (!_webViewPlaceholder) { _webViewPlaceholder.adoptNS([[NSImageView alloc] init]); @@ -245,7 +251,7 @@ static RetainPtr<CGImageRef> createImageWithCopiedData(CGImageRef sourceImage) [_webViewPlaceholder.get() setWantsLayer:YES]; } [[_webViewPlaceholder.get() layer] setContents:(id)webViewContents.get()]; - [self _swapView:_webView with:_webViewPlaceholder.get()]; + [self _replaceView:_webView with:_webViewPlaceholder.get()]; // Then insert the WebView into the full screen window NSView* contentView = [[self window] contentView]; @@ -322,10 +328,14 @@ static RetainPtr<CGImageRef> createImageWithCopiedData(CGImageRef sourceImage) return; _isFullScreen = NO; - // Screen updates to be re-enabled in beganExitFullScreenWithInitialFrame:finalFrame: + // Screen updates to be re-enabled in _startExitFullScreenAnimationWithDuration: NSDisableScreenUpdates(); [[self window] setAutodisplay:NO]; + // See the related comment in enterFullScreen: + // We will resume the normal behavior in _startExitFullScreenAnimationWithDuration: + [_webView _setSuppressVisibilityUpdates:YES]; + [self _manager]->setAnimatingFullScreen(true); [self _manager]->willExitFullScreen(); } @@ -380,7 +390,7 @@ static void completeFinishExitFullScreenAnimationAfterRepaint(WKErrorRef, void*) [[_webViewPlaceholder.get() window] setAutodisplay:NO]; NSResponder *firstResponder = [[self window] firstResponder]; - [self _swapView:_webViewPlaceholder.get() with:_webView]; + [self _replaceView:_webViewPlaceholder.get() with:_webView]; [[_webView window] makeResponder:firstResponder firstResponderIfDescendantOfView:_webView]; NSRect windowBounds = [[self window] frame]; @@ -487,7 +497,7 @@ static void completeFinishExitFullScreenAnimationAfterRepaint(WKErrorRef, void* return webPage->fullScreenManager(); } -- (void)_swapView:(NSView*)view with:(NSView*)otherView +- (void)_replaceView:(NSView*)view with:(NSView*)otherView { [CATransaction begin]; [CATransaction setDisableActions:YES]; @@ -566,6 +576,7 @@ static NSRect windowFrameFromApparentFrames(NSRect screenFrame, NSRect initialFr [_backgroundWindow.get() orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; + [_webView _setSuppressVisibilityUpdates:NO]; [[self window] setAutodisplay:YES]; [[self window] displayIfNeeded]; NSEnableScreenUpdates(); @@ -610,6 +621,7 @@ static NSRect windowFrameFromApparentFrames(NSRect screenFrame, NSRect initialFr finalBounds.origin = [[self window] convertScreenToBase:finalBounds.origin]; WKWindowSetClipRect([self window], finalBounds); + [_webView _setSuppressVisibilityUpdates:NO]; [[self window] setAutodisplay:YES]; [[self window] displayIfNeeded]; NSEnableScreenUpdates(); diff --git a/Source/WebKit2/UIProcess/mac/WebContextMac.mm b/Source/WebKit2/UIProcess/mac/WebContextMac.mm index 243027974..438183a23 100644 --- a/Source/WebKit2/UIProcess/mac/WebContextMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebContextMac.mm @@ -33,7 +33,7 @@ #import <WebCore/PlatformPasteboard.h> #import <sys/param.h> -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if HAVE(HOSTED_CORE_ANIMATION) && !defined(BUILDING_ON_SNOW_LEOPARD) #import <QuartzCore/CARemoteLayerServer.h> #endif diff --git a/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm index 6325fca45..b8427d56f 100644 --- a/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm @@ -26,13 +26,13 @@ #import "config.h" #import "WebFullScreenManagerProxy.h" +#if ENABLE(FULLSCREEN_API) + #import "LayerTreeContext.h" #import "WKFullScreenWindowController.h" #import "WKViewInternal.h" #import <WebCore/IntRect.h> -#if ENABLE(FULLSCREEN_API) - using namespace WebCore; namespace WebKit { diff --git a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm index a4ae7eac7..96712bf0c 100644 --- a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm @@ -27,6 +27,7 @@ #import "WebPageProxy.h" #import "AttributedString.h" +#import "ColorSpaceData.h" #import "DataReference.h" #import "DictionaryPopupInfo.h" #import "EditorState.h" @@ -38,15 +39,15 @@ #import "TextChecker.h" #import "WebPageMessages.h" #import "WebProcessProxy.h" +#import <WebCore/DictationAlternative.h> #import <WebCore/SharedBuffer.h> +#import <WebCore/TextAlternativeWithRange.h> #import <WebKitSystemInterface.h> #import <wtf/text/StringConcatenate.h> -#if USE(APPKIT) @interface NSApplication (Details) - (void)speakString:(NSString *)string; @end -#endif #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection()) @@ -123,8 +124,6 @@ String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent return makeString("Mozilla/5.0 (Macintosh; " PROCESSOR " Mac OS X ", osVersion, ") AppleWebKit/", webKitVersion, " (KHTML, like Gecko) ", applicationNameForUserAgent); } -#if USE(APPKIT) - void WebPageProxy::getIsSpeaking(bool& isSpeaking) { isSpeaking = [NSApp isSpeaking]; @@ -145,8 +144,6 @@ void WebPageProxy::searchWithSpotlight(const String& string) [[NSWorkspace sharedWorkspace] showSearchResultsForQueryString:nsStringFromWebCoreString(string)]; } -#endif // USE(APPKIT) - CGContextRef WebPageProxy::containingWindowGraphicsContext() { return m_pageClient->containingWindowGraphicsContext(); @@ -204,6 +201,35 @@ bool WebPageProxy::insertText(const String& text, uint64_t replacementRangeStart return handled; } +bool WebPageProxy::insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<TextAlternativeWithRange>& dictationAlternativesWithRange) +{ +#if USE(DICTATION_ALTERNATIVES) + if (dictationAlternativesWithRange.isEmpty()) + return insertText(text, replacementRangeStart, replacementRangeEnd); + + if (!isValid()) + return true; + + Vector<DictationAlternative> dictationAlternatives; + + for (size_t i = 0; i < dictationAlternativesWithRange.size(); ++i) { + const TextAlternativeWithRange& alternativeWithRange = dictationAlternativesWithRange[i]; + uint64_t dictationContext = m_pageClient->addDictationAlternatives(alternativeWithRange.alternatives); + if (dictationContext) + dictationAlternatives.append(DictationAlternative(alternativeWithRange.range.location, alternativeWithRange.range.length, dictationContext)); + } + + if (dictationAlternatives.isEmpty()) + return insertText(text, replacementRangeStart, replacementRangeEnd); + + bool handled = true; + process()->sendSync(Messages::WebPage::InsertDictatedText(text, replacementRangeStart, replacementRangeEnd, dictationAlternatives), Messages::WebPage::InsertDictatedText::Reply(handled, m_editorState), m_pageID); + return handled; +#else + return insertText(text, replacementRangeStart, replacementRangeEnd); +#endif +} + void WebPageProxy::getMarkedRange(uint64_t& location, uint64_t& length) { location = NSNotFound; @@ -387,7 +413,12 @@ void WebPageProxy::makeFirstResponder() { m_pageClient->makeFirstResponder(); } - + +ColorSpaceData WebPageProxy::colorSpace() +{ + return m_pageClient->colorSpace(); +} + void WebPageProxy::registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elementToken, const CoreIPC::DataReference& windowToken) { if (!isValid()) diff --git a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp index 3c2196b04..93b6415c3 100644 --- a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp +++ b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp @@ -41,9 +41,9 @@ void QtGestureRecognizer::reset() m_state = NoGesture; } -QtViewportInteractionEngine* QtGestureRecognizer::interactionEngine() +QtViewportHandler* QtGestureRecognizer::viewportHandler() { - return m_eventHandler->interactionEngine(); + return m_eventHandler->viewportHandler(); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h index 5af3ba6b5..68e032f47 100644 --- a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h +++ b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h @@ -28,7 +28,7 @@ namespace WebKit { -class QtViewportInteractionEngine; +class QtViewportHandler; class QtWebPageEventHandler; class QtGestureRecognizer { @@ -46,7 +46,7 @@ protected: GestureRecognized } m_state; - QtViewportInteractionEngine* interactionEngine(); + QtViewportHandler* viewportHandler(); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp index 118373844..4c28b93cf 100644 --- a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp @@ -25,7 +25,7 @@ #include "config.h" #include "QtPanGestureRecognizer.h" -#include "QtViewportInteractionEngine.h" +#include "QtViewportHandler.h" #include "QtWebPageEventHandler.h" namespace WebKit { @@ -38,7 +38,7 @@ QtPanGestureRecognizer::QtPanGestureRecognizer(QtWebPageEventHandler* eventHandl bool QtPanGestureRecognizer::update(const QTouchEvent::TouchPoint& touchPoint, qint64 eventTimestampMillis) { - if (!interactionEngine()) + if (!viewportHandler()) return false; m_lastPosition = touchPoint.pos(); @@ -48,7 +48,7 @@ bool QtPanGestureRecognizer::update(const QTouchEvent::TouchPoint& touchPoint, q case NoGesture: m_state = GestureRecognitionStarted; m_firstScreenPosition = touchPoint.scenePos(); - interactionEngine()->cancelScrollAnimation(); + viewportHandler()->cancelScrollAnimation(); return false; case GestureRecognitionStarted: { // To start the gesture, the delta from start in screen coordinates @@ -58,11 +58,11 @@ bool QtPanGestureRecognizer::update(const QTouchEvent::TouchPoint& touchPoint, q return false; m_state = GestureRecognized; - interactionEngine()->panGestureStarted(touchPoint.pos(), eventTimestampMillis); + viewportHandler()->panGestureStarted(touchPoint.pos(), eventTimestampMillis); return true; } case GestureRecognized: - interactionEngine()->panGestureRequestUpdate(touchPoint.pos(), eventTimestampMillis); + viewportHandler()->panGestureRequestUpdate(touchPoint.pos(), eventTimestampMillis); return true; default: ASSERT_NOT_REACHED(); @@ -75,8 +75,8 @@ void QtPanGestureRecognizer::finish(const QTouchEvent::TouchPoint& touchPoint, q if (m_state == NoGesture) return; - ASSERT(interactionEngine()); - interactionEngine()->panGestureEnded(touchPoint.pos(), eventTimestampMillis); + ASSERT(viewportHandler()); + viewportHandler()->panGestureEnded(touchPoint.pos(), eventTimestampMillis); reset(); } @@ -85,8 +85,8 @@ void QtPanGestureRecognizer::cancel() if (m_state == NoGesture) return; - interactionEngine()->panGestureEnded(m_lastPosition, m_lastEventTimestampMillis); - interactionEngine()->panGestureCancelled(); + viewportHandler()->panGestureEnded(m_lastPosition, m_lastEventTimestampMillis); + viewportHandler()->panGestureCancelled(); reset(); } diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp index 0d57ffa05..75d4d23b0 100644 --- a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp @@ -26,7 +26,7 @@ #include "config.h" #include "QtPinchGestureRecognizer.h" -#include "QtViewportInteractionEngine.h" +#include "QtViewportHandler.h" #include "QtWebPageEventHandler.h" #include <QtCore/QLineF> @@ -47,7 +47,7 @@ QtPinchGestureRecognizer::QtPinchGestureRecognizer(QtWebPageEventHandler* eventH bool QtPinchGestureRecognizer::update(const QTouchEvent::TouchPoint& point1, const QTouchEvent::TouchPoint& point2) { - ASSERT(interactionEngine()); + ASSERT(viewportHandler()); const qreal currentFingerDistance = QLineF(point1.screenPos(), point2.screenPos()).length(); switch (m_state) { case NoGesture: @@ -59,7 +59,7 @@ bool QtPinchGestureRecognizer::update(const QTouchEvent::TouchPoint& point1, con if (pinchDistance < pinchInitialTriggerDistanceThreshold) return false; m_state = GestureRecognized; - interactionEngine()->pinchGestureStarted(computePinchCenter(point1, point2)); + viewportHandler()->pinchGestureStarted(computePinchCenter(point1, point2)); // We reset the initial span distance to the current distance of the // touch points in order to avoid the jump caused by the events which @@ -71,7 +71,7 @@ bool QtPinchGestureRecognizer::update(const QTouchEvent::TouchPoint& point1, con case GestureRecognized: const qreal totalScaleFactor = currentFingerDistance / m_initialFingerDistance; const QPointF touchCenterInViewCoordinates = computePinchCenter(point1, point2); - interactionEngine()->pinchGestureRequestUpdate(touchCenterInViewCoordinates, totalScaleFactor); + viewportHandler()->pinchGestureRequestUpdate(touchCenterInViewCoordinates, totalScaleFactor); return true; break; } @@ -85,8 +85,8 @@ void QtPinchGestureRecognizer::finish() if (m_state == NoGesture) return; - ASSERT(interactionEngine()); - interactionEngine()->pinchGestureEnded(); + ASSERT(viewportHandler()); + viewportHandler()->pinchGestureEnded(); reset(); } @@ -95,8 +95,8 @@ void QtPinchGestureRecognizer::cancel() if (m_state == NoGesture) return; - ASSERT(interactionEngine()); - interactionEngine()->pinchGestureCancelled(); + ASSERT(viewportHandler()); + viewportHandler()->pinchGestureCancelled(); reset(); } diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp index 007659b2f..eea6385bb 100644 --- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp +++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,73 +27,92 @@ #include "QtWebPageEventHandler.h" #include <QLineF> -#include <QTouchEvent> namespace WebKit { +// FIXME: These constants should possibly depend on DPI. +static const int panDistanceThreshold = 10; +static const int maxDoubleTapDistance = 120; + +// FIXME: These constants should possibly be consistent across the platform. +static const int tapAndHoldTime = 1000; +static const int maxDoubleTapInterval = 500; +static const int highlightDelay = 100; + + QtTapGestureRecognizer::QtTapGestureRecognizer(QtWebPageEventHandler* eventHandler) : QtGestureRecognizer(eventHandler) - , m_candidate(Invalid) + , m_candidate(SingleTapCandidate) { } bool QtTapGestureRecognizer::withinDistance(const QTouchEvent::TouchPoint& touchPoint, int distance) { + ASSERT(m_lastTouchPoint.id() != -1); return QLineF(touchPoint.screenPos(), m_lastTouchPoint.screenPos()).length() < distance; } -bool QtTapGestureRecognizer::update(QEvent::Type eventType, const QTouchEvent::TouchPoint& touchPoint) +void QtTapGestureRecognizer::update(const QTouchEvent::TouchPoint& touchPoint) { - ASSERT(m_eventHandler); - - switch (eventType) { - case QEvent::TouchBegin: + switch (m_state) { + case NoGesture: m_doubleTapTimer.stop(); // Cancel other pending single tap event. + m_state = GestureRecognitionStarted; ASSERT(!m_tapAndHoldTimer.isActive()); m_tapAndHoldTimer.start(tapAndHoldTime, this); - if (m_lastTouchPoint.id() != -1 && withinDistance(touchPoint, maxDoubleTapDistance)) - m_candidate = DoubleTapCandidate; - else { - m_candidate = SingleTapCandidate; - // The below in facts resets any previous single tap event. - m_highlightTimer.start(highlightDelay, this); - m_lastTouchPoint = touchPoint; - m_doubleTapTimer.start(maxDoubleTapInterval, this); - } - break; + // Early return if this is the second touch point of a potential double tap gesture. + if (m_candidate == DoubleTapCandidate && withinDistance(touchPoint, maxDoubleTapDistance)) + return; - case QEvent::TouchUpdate: + // The below in fact resets any previous single tap event. + m_candidate = SingleTapCandidate; + m_lastTouchPoint = touchPoint; + m_highlightTimer.start(highlightDelay, this); + m_doubleTapTimer.start(maxDoubleTapInterval, this); + break; + case GestureRecognitionStarted: // If the touch point moves further than the threshold, we cancel the tap gesture. - if (m_candidate != Invalid && !withinDistance(touchPoint, maxPanDistance)) + if (!withinDistance(touchPoint, panDistanceThreshold)) reset(); break; + default: + ASSERT_NOT_REACHED(); + break; + } +} - case QEvent::TouchEnd: - m_tapAndHoldTimer.stop(); - - if (m_candidate == Invalid) - break; +void QtTapGestureRecognizer::finish(const QTouchEvent::TouchPoint& touchPoint) +{ + ASSERT(m_eventHandler); + m_tapAndHoldTimer.stop(); - if (m_candidate == DoubleTapCandidate) { - m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); - m_eventHandler->handleDoubleTapEvent(touchPoint); - reset(); - } + // Gesture has been cancelled, ignore. + if (m_state == NoGesture) + return; - break; + m_state = NoGesture; - default: - break; - } + if (m_candidate == SingleTapCandidate) { + if (m_doubleTapTimer.isActive()) { + m_candidate = DoubleTapCandidate; + m_lastTouchPoint = touchPoint; + // Early return since this is a potential double tap gesture. + return; + } + // This happens when the finger is released (gesture finished) after the single + // tap timeout elapsed (500ms) but before the tap-and-hold timeout (1000ms) fired. + m_eventHandler->handleSingleTapEvent(touchPoint); + } else // DoubleTapCandidate + m_eventHandler->handleDoubleTapEvent(touchPoint); - return false; + reset(); } void QtTapGestureRecognizer::cancel() { - if (m_candidate == Invalid) + if (m_lastTouchPoint.id() == -1) return; reset(); @@ -103,27 +122,22 @@ void QtTapGestureRecognizer::highlightTimeout() { m_highlightTimer.stop(); - if (m_candidate != SingleTapCandidate) + // Gesture has been cancelled, ignore. + if (m_lastTouchPoint.id() == -1) return; - ASSERT(m_lastTouchPoint.id() != -1); - m_eventHandler->handlePotentialSingleTapEvent(m_lastTouchPoint); + m_eventHandler->activateTapHighlight(m_lastTouchPoint); } void QtTapGestureRecognizer::singleTapTimeout() { m_doubleTapTimer.stop(); - // Finger is still pressed, ignore. - if (m_tapAndHoldTimer.isActive()) + // Finger is still pressed or gesture has been cancelled, ignore. + if (m_tapAndHoldTimer.isActive() || m_lastTouchPoint.id() == -1) return; - ASSERT(m_lastTouchPoint.id() != -1); - - if (m_candidate == SingleTapCandidate) { - m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); - m_eventHandler->handleSingleTapEvent(m_lastTouchPoint); - } + m_eventHandler->handleSingleTapEvent(m_lastTouchPoint); reset(); } @@ -131,9 +145,11 @@ void QtTapGestureRecognizer::tapAndHoldTimeout() { m_tapAndHoldTimer.stop(); - ASSERT(m_lastTouchPoint.id() != -1); + // Gesture has been cancelled, ignore. + if (m_lastTouchPoint.id() == -1) + return; + #if 0 // No support for synthetic context menus in WK2 yet. - m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); m_eventHandler->handleTapAndHoldEvent(m_lastTouchPoint); #endif reset(); @@ -141,10 +157,9 @@ void QtTapGestureRecognizer::tapAndHoldTimeout() void QtTapGestureRecognizer::reset() { - if (m_candidate != Invalid) - m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); + m_eventHandler->deactivateTapHighlight(); - m_candidate = Invalid; + m_candidate = SingleTapCandidate; m_lastTouchPoint.setId(-1); m_highlightTimer.stop(); m_doubleTapTimer.stop(); diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h index 2cbcf9375..affbc38c5 100644 --- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h +++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h @@ -31,13 +31,6 @@ #include <QtCore/QBasicTimer> #include <QtCore/QObject> -// FIXME: These constants should possibly depend on DPI. -const int maxPanDistance = 10; -const int maxDoubleTapDistance = 120; -const int tapAndHoldTime = 800; -const int maxDoubleTapInterval = 400; -const int highlightDelay = 80; - namespace WebKit { class QtWebPageEventHandler; @@ -45,7 +38,8 @@ class QtWebPageEventHandler; class QtTapGestureRecognizer : public QObject, private QtGestureRecognizer { public: QtTapGestureRecognizer(QtWebPageEventHandler*); - bool update(QEvent::Type eventType, const QTouchEvent::TouchPoint&); + void update(const QTouchEvent::TouchPoint&); + void finish(const QTouchEvent::TouchPoint&); void cancel(); protected: @@ -64,9 +58,8 @@ private: QTouchEvent::TouchPoint m_lastTouchPoint; enum { - Invalid, SingleTapCandidate, - DoubleTapCandidate, + DoubleTapCandidate } m_candidate; }; diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportHandler.cpp index 053afff29..548819e13 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp +++ b/Source/WebKit2/UIProcess/qt/QtViewportHandler.cpp @@ -20,7 +20,7 @@ */ #include "config.h" -#include "QtViewportInteractionEngine.h" +#include "QtViewportHandler.h" #include "WebPageGroup.h" #include "WebPageProxy.h" @@ -65,33 +65,38 @@ static const int kScaleAnimationDurationMillis = 250; class ViewportUpdateDeferrer { public: enum SuspendContentFlag { DeferUpdate, DeferUpdateAndSuspendContent }; - ViewportUpdateDeferrer(QtViewportInteractionEngine* engine, SuspendContentFlag suspendContentFlag = DeferUpdate) - : engine(engine) + ViewportUpdateDeferrer(QtViewportHandler* handler, SuspendContentFlag suspendContentFlag = DeferUpdate) + : handler(handler) { - engine->m_suspendCount++; + handler->m_suspendCount++; // There is no need to suspend content for immediate updates // only during animations or longer gestures. if (suspendContentFlag == DeferUpdateAndSuspendContent) - engine->suspendPageContent(); + handler->suspendPageContent(); } ~ViewportUpdateDeferrer() { - if (--(engine->m_suspendCount)) + // We are calling setInitialScaleIfNeeded() here as it requires a + // possitive m_suspendCount due to the assert in setPageItemRectVisible(). + if (handler->m_suspendCount == 1) + handler->setInitialScaleIfNeeded(); + + if (--(handler->m_suspendCount)) return; - engine->resumePageContent(); + handler->resumePageContent(); // Make sure that tiles all around the viewport will be requested. - engine->informVisibleContentChange(QPointF()); + handler->informVisibleContentChange(QPointF()); } private: - QtViewportInteractionEngine* const engine; + QtViewportHandler* const handler; }; -void QtViewportInteractionEngine::suspendPageContent() +void QtViewportHandler::suspendPageContent() { if (m_hasSuspendedContent) return; @@ -100,7 +105,7 @@ void QtViewportInteractionEngine::suspendPageContent() m_webPageProxy->suspendActiveDOMObjectsAndAnimations(); } -void QtViewportInteractionEngine::resumePageContent() +void QtViewportHandler::resumePageContent() { if (!m_hasSuspendedContent) return; @@ -114,17 +119,17 @@ static inline bool fuzzyCompare(qreal a, qreal b, qreal epsilon) return qAbs(a - b) < epsilon; } -inline qreal QtViewportInteractionEngine::cssScaleFromItem(qreal itemScale) const +inline qreal QtViewportHandler::cssScaleFromItem(qreal itemScale) const { return itemScale / m_devicePixelRatio; } -inline qreal QtViewportInteractionEngine::itemScaleFromCSS(qreal cssScale) const +inline qreal QtViewportHandler::itemScaleFromCSS(qreal cssScale) const { return cssScale * m_devicePixelRatio; } -inline qreal QtViewportInteractionEngine::itemCoordFromCSS(qreal value) const +inline qreal QtViewportHandler::itemCoordFromCSS(qreal value) const { return value * m_devicePixelRatio; } @@ -135,7 +140,7 @@ static inline QPointF boundPosition(const QPointF minPosition, const QPointF& po qBound(minPosition.y(), position.y(), maxPosition.y())); } -inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect) const +inline QRectF QtViewportHandler::itemRectFromCSS(const QRectF& cssRect) const { QRectF itemRect; @@ -147,7 +152,7 @@ inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect return itemRect; } -QtViewportInteractionEngine::QtViewportInteractionEngine(WebKit::WebPageProxy* proxy, QQuickWebView* viewportItem, QQuickWebPage* pageItem) +QtViewportHandler::QtViewportHandler(WebKit::WebPageProxy* proxy, QQuickWebView* viewportItem, QQuickWebPage* pageItem) : m_webPageProxy(proxy) , m_viewportItem(viewportItem) , m_pageItem(pageItem) @@ -163,6 +168,9 @@ QtViewportInteractionEngine::QtViewportInteractionEngine(WebKit::WebPageProxy* p , m_lastCommittedScale(-1) , m_zoomOutScale(0.0) { + m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); + m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic); + connect(m_viewportItem, SIGNAL(movementStarted()), SLOT(flickMoveStarted()), Qt::DirectConnection); connect(m_viewportItem, SIGNAL(movementEnded()), SLOT(flickMoveEnded()), Qt::DirectConnection); @@ -172,16 +180,16 @@ QtViewportInteractionEngine::QtViewportInteractionEngine(WebKit::WebPageProxy* p SLOT(scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), Qt::DirectConnection); } -QtViewportInteractionEngine::~QtViewportInteractionEngine() +QtViewportHandler::~QtViewportHandler() { } -qreal QtViewportInteractionEngine::innerBoundedCSSScale(qreal cssScale) const +qreal QtViewportHandler::innerBoundedCSSScale(qreal cssScale) const { return qBound(m_minimumScale, cssScale, m_maximumScale); } -qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale) const +qreal QtViewportHandler::outerBoundedCSSScale(qreal cssScale) const { if (m_allowsUserScaling) { // Bounded by [0.1, 10.0] like the viewport meta code in WebCore. @@ -192,54 +200,43 @@ qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale) const return innerBoundedCSSScale(cssScale); } -void QtViewportInteractionEngine::viewportAttributesChanged(const WebCore::ViewportAttributes& newAttributes) +void QtViewportHandler::setInitialScaleIfNeeded() { - m_rawAttributes = newAttributes; - WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes); + if (m_rawAttributes.layoutSize.isEmpty() || m_rawAttributes.initialScale < 0) + return; - { - // FIXME: Resetting here is wrong, it should happen only for the first - // viewport change for a given page and first when we paint the page for - // the first time. + m_zoomOutScale = 0.0; + m_scaleStack.clear(); - m_hadUserInteraction = false; + m_hadUserInteraction = false; - m_zoomOutScale = 0.0; - m_scaleStack.clear(); + // We must not animate here as the new contents size might be very different + // than the current one. + setPageItemRectVisible(initialRect()); - // This part below should go fully away when the above plan is implemented. + m_rawAttributes.initialScale = -1; // Mark used. +} - m_viewportItem->cancelFlick(); - m_scaleAnimation->stop(); +void QtViewportHandler::viewportAttributesChanged(const WebCore::ViewportAttributes& newAttributes) +{ + if (newAttributes.layoutSize.isEmpty()) + return; - m_scaleUpdateDeferrer.clear(); - m_scrollUpdateDeferrer.clear(); - m_touchUpdateDeferrer.clear(); - m_animationUpdateDeferrer.clear(); - ASSERT(!m_suspendCount); - ASSERT(!m_hasSuspendedContent); - } + m_rawAttributes = newAttributes; + WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes); m_devicePixelRatio = m_rawAttributes.devicePixelRatio; // Should return value from the webPageProxy. m_allowsUserScaling = !!m_rawAttributes.userScalable; m_minimumScale = m_rawAttributes.minimumScale; m_maximumScale = m_rawAttributes.maximumScale; - if (!m_hadUserInteraction && !m_hasSuspendedContent) { - ASSERT(m_pinchStartScale == -1); - // Emits contentsScaleChanged(); - setCSSScale(m_rawAttributes.initialScale); - } + // Make sure we apply the new initial scale when deferring ends. + ViewportUpdateDeferrer guard(this); 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) +void QtViewportHandler::pageContentsSizeChanged(const QSize& newSize, const QSize& viewportSize) { float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, viewportSize, newSize); @@ -257,11 +254,13 @@ void QtViewportInteractionEngine::pageContentsSizeChanged(const QSize& newSize, // we didn't do scale adjustment. emit m_viewportItem->experimental()->test()->contentsScaleCommitted(); - ViewportUpdateDeferrer guard(this); - setPageItemRectVisible(nearestValidBounds()); + if (!m_hasSuspendedContent) { + ViewportUpdateDeferrer guard(this); + setPageItemRectVisible(nearestValidBounds()); + } } -void QtViewportInteractionEngine::setPageItemRectVisible(const QRectF& itemRect) +void QtViewportHandler::setPageItemRectVisible(const QRectF& itemRect) { ASSERT_WITH_MESSAGE(m_suspendCount, "setPageItemRectVisible has to be guarded using a ViewportUpdateDeferrer."); @@ -280,13 +279,7 @@ void QtViewportInteractionEngine::setPageItemRectVisible(const QRectF& itemRect) m_viewportItem->setContentPos(newPosition); } -// Ease out overshoot of 1.25 combined with ease in correction of 0.25. Both quadratic to have physical motion. -static qreal physicalOvershoot(qreal t) -{ - return (-t * (t - 2)) * 1.25 - (t * t) * 0.25; -} - -void QtViewportInteractionEngine::animatePageItemRectVisible(const QRectF& itemRect) +void QtViewportHandler::animatePageItemRectVisible(const QRectF& itemRect) { ASSERT(m_scaleAnimation->state() == QAbstractAnimation::Stopped); @@ -298,19 +291,13 @@ void QtViewportInteractionEngine::animatePageItemRectVisible(const QRectF& itemR if (itemRect == currentPageItemRectVisible) return; - QEasingCurve easingCurve; - easingCurve.setCustomType(physicalOvershoot); - - m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); - m_scaleAnimation->setEasingCurve(easingCurve); - m_scaleAnimation->setStartValue(currentPageItemRectVisible); m_scaleAnimation->setEndValue(itemRect); m_scaleAnimation->start(); } -void QtViewportInteractionEngine::flickMoveStarted() +void QtViewportHandler::flickMoveStarted() { Q_ASSERT(m_viewportItem->isMoving()); m_scrollUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); @@ -320,7 +307,7 @@ void QtViewportInteractionEngine::flickMoveStarted() connect(m_viewportItem, SIGNAL(contentYChanged()), SLOT(pageItemPositionChanged())); } -void QtViewportInteractionEngine::flickMoveEnded() +void QtViewportHandler::flickMoveEnded() { Q_ASSERT(!m_viewportItem->isMoving()); // This method is called on the end of the pan or pan kinetic animation. @@ -331,7 +318,7 @@ void QtViewportInteractionEngine::flickMoveEnded() disconnect(m_viewportItem, SIGNAL(contentYChanged()), this, SLOT(pageItemPositionChanged())); } -void QtViewportInteractionEngine::pageItemPositionChanged() +void QtViewportHandler::pageItemPositionChanged() { QPointF newPosition = m_viewportItem->contentPos(); @@ -340,7 +327,7 @@ void QtViewportInteractionEngine::pageItemPositionChanged() m_lastScrollPosition = newPosition; } -void QtViewportInteractionEngine::pageContentPositionRequested(const QPoint& cssPosition) +void QtViewportHandler::pageContentPositionRequested(const QPoint& cssPosition) { // Ignore the request if suspended. Can only happen due to delay in event delivery. if (m_suspendCount) @@ -357,7 +344,7 @@ void QtViewportInteractionEngine::pageContentPositionRequested(const QPoint& css setPageItemRectVisible(endVisibleContentRect); } -void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/) +void QtViewportHandler::scaleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/) { switch (newState) { case QAbstractAnimation::Running: @@ -373,12 +360,19 @@ void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation: } } -void QtViewportInteractionEngine::scaleAnimationValueChanged(QVariant value) +void QtViewportHandler::scaleAnimationValueChanged(QVariant value) { + // Resetting the end value, the easing curve or the duration of the scale animation + // triggers a recalculation of the animation interval. This might change the current + // value of the animated property. + // Make sure we only act on animation value changes if the animation is active. + if (!scaleAnimationActive()) + return; + setPageItemRectVisible(value.toRectF()); } -void QtViewportInteractionEngine::touchBegin() +void QtViewportHandler::touchBegin() { m_hadUserInteraction = true; @@ -387,12 +381,12 @@ void QtViewportInteractionEngine::touchBegin() m_touchUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); } -void QtViewportInteractionEngine::touchEnd() +void QtViewportHandler::touchEnd() { m_touchUpdateDeferrer.clear(); } -QRectF QtViewportInteractionEngine::computePosRangeForPageItemAtScale(qreal itemScale) const +QRectF QtViewportHandler::computePosRangeForPageItemAtScale(qreal itemScale) const { const QSizeF contentItemSize = m_pageItem->contentsSize() * itemScale; const QSizeF viewportItemSize = m_viewportItem->boundingRect().size(); @@ -403,7 +397,7 @@ QRectF QtViewportInteractionEngine::computePosRangeForPageItemAtScale(qreal item return QRectF(QPointF(0, 0), QSizeF(horizontalRange, verticalRange)); } -void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, const QRectF& targetArea) +void QtViewportHandler::focusEditableArea(const QRectF& caretArea, const QRectF& targetArea) { // This can only happen as a result of a user interaction. ASSERT(m_hadUserInteraction); @@ -440,7 +434,7 @@ void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, con animatePageItemRectVisible(endVisibleContentRect); } -void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea) +void QtViewportHandler::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea) { // This can only happen as a result of a user interaction. ASSERT(m_hadUserInteraction); @@ -524,7 +518,18 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi animatePageItemRectVisible(endVisibleContentRect); } -QRectF QtViewportInteractionEngine::nearestValidBounds() const +QRectF QtViewportHandler::initialRect() const +{ + ASSERT(m_rawAttributes.initialScale > 0); + + qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(m_rawAttributes.initialScale)); + const QRectF viewportRect = m_viewportItem->boundingRect(); + QRectF endVisibleContentRect(QPointF(0, 0), viewportRect.size() / endItemScale); + + return endVisibleContentRect; +} + +QRectF QtViewportHandler::nearestValidBounds() const { qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(currentCSSScale())); @@ -541,7 +546,7 @@ QRectF QtViewportInteractionEngine::nearestValidBounds() const return endVisibleContentRect; } -void QtViewportInteractionEngine::setCSSScale(qreal scale) +void QtViewportHandler::setCSSScale(qreal scale) { ViewportUpdateDeferrer guard(this); @@ -549,22 +554,22 @@ void QtViewportInteractionEngine::setCSSScale(qreal scale) m_pageItem->setContentsScale(itemScaleFromCSS(newScale)); } -qreal QtViewportInteractionEngine::currentCSSScale() const +qreal QtViewportHandler::currentCSSScale() const { return cssScaleFromItem(m_pageItem->contentsScale()); } -bool QtViewportInteractionEngine::scrollAnimationActive() const +bool QtViewportHandler::scrollAnimationActive() const { return m_viewportItem->isFlicking(); } -bool QtViewportInteractionEngine::panGestureActive() const +bool QtViewportHandler::panGestureActive() const { return m_viewportItem->isDragging(); } -void QtViewportInteractionEngine::panGestureStarted(const QPointF& position, qint64 eventTimestampMillis) +void QtViewportHandler::panGestureStarted(const QPointF& position, qint64 eventTimestampMillis) { // This can only happen as a result of a user interaction. ASSERT(m_hadUserInteraction); @@ -573,19 +578,19 @@ void QtViewportInteractionEngine::panGestureStarted(const QPointF& position, qin m_lastPinchCenterInViewportCoordinates = position; } -void QtViewportInteractionEngine::panGestureRequestUpdate(const QPointF& position, qint64 eventTimestampMillis) +void QtViewportHandler::panGestureRequestUpdate(const QPointF& position, qint64 eventTimestampMillis) { m_viewportItem->handleFlickableMouseMove(position, eventTimestampMillis); m_lastPinchCenterInViewportCoordinates = position; } -void QtViewportInteractionEngine::panGestureEnded(const QPointF& position, qint64 eventTimestampMillis) +void QtViewportHandler::panGestureEnded(const QPointF& position, qint64 eventTimestampMillis) { m_viewportItem->handleFlickableMouseRelease(position, eventTimestampMillis); m_lastPinchCenterInViewportCoordinates = position; } -void QtViewportInteractionEngine::panGestureCancelled() +void QtViewportHandler::panGestureCancelled() { // Reset the velocity samples of the flickable. // This should only be called by the recognizer if we have a recognized @@ -597,12 +602,12 @@ void QtViewportInteractionEngine::panGestureCancelled() m_viewportItem->cancelFlick(); } -bool QtViewportInteractionEngine::scaleAnimationActive() const +bool QtViewportHandler::scaleAnimationActive() const { return m_scaleAnimation->state() == QAbstractAnimation::Running; } -void QtViewportInteractionEngine::cancelScrollAnimation() +void QtViewportHandler::cancelScrollAnimation() { if (!scrollAnimationActive()) return; @@ -617,18 +622,18 @@ void QtViewportInteractionEngine::cancelScrollAnimation() setPageItemRectVisible(nearestValidBounds()); } -void QtViewportInteractionEngine::interruptScaleAnimation() +void QtViewportHandler::interruptScaleAnimation() { // This interrupts the scale animation exactly where it is, even if it is out of bounds. m_scaleAnimation->stop(); } -bool QtViewportInteractionEngine::pinchGestureActive() const +bool QtViewportHandler::pinchGestureActive() const { return m_pinchStartScale > 0; } -void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenterInViewportCoordinates) +void QtViewportHandler::pinchGestureStarted(const QPointF& pinchCenterInViewportCoordinates) { // This can only happen as a result of a user interaction. ASSERT(m_hadUserInteraction); @@ -645,7 +650,7 @@ void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenter m_pinchStartScale = m_pageItem->contentsScale(); } -void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor) +void QtViewportHandler::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor) { ASSERT(m_suspendCount); @@ -667,7 +672,7 @@ void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinch m_viewportItem->setContentPos(m_viewportItem->contentPos() - positionDiff); } -void QtViewportInteractionEngine::pinchGestureEnded() +void QtViewportHandler::pinchGestureEnded() { ASSERT(m_suspendCount); @@ -680,13 +685,13 @@ void QtViewportInteractionEngine::pinchGestureEnded() m_scaleUpdateDeferrer.clear(); // Clear after starting potential animation, which takes over deferring. } -void QtViewportInteractionEngine::pinchGestureCancelled() +void QtViewportHandler::pinchGestureCancelled() { m_pinchStartScale = -1; m_scaleUpdateDeferrer.clear(); } -QRect QtViewportInteractionEngine::visibleContentsRect() const +QRect QtViewportHandler::visibleContentsRect() const { const QRectF visibleRect(m_viewportItem->boundingRect().intersected(m_pageItem->boundingRect())); @@ -695,7 +700,7 @@ QRect QtViewportInteractionEngine::visibleContentsRect() const return QRect(floor(mappedRect.x()), floor(mappedRect.y()), floor(mappedRect.width()), floor(mappedRect.height())); } -void QtViewportInteractionEngine::informVisibleContentChange(const QPointF& trajectoryVector) +void QtViewportHandler::informVisibleContentChange(const QPointF& trajectoryVector) { DrawingAreaProxy* drawingArea = m_webPageProxy->drawingArea(); if (!drawingArea) @@ -717,18 +722,13 @@ void QtViewportInteractionEngine::informVisibleContentChange(const QPointF& traj m_pageItem->update(); } -void QtViewportInteractionEngine::viewportItemSizeChanged() +void QtViewportHandler::viewportItemSizeChanged() { QSize viewportSize = m_viewportItem->boundingRect().size().toSize(); if (viewportSize.isEmpty()) return; - // FIXME: This is wrong, add QML api! - WebPreferences* wkPrefs = m_webPageProxy->pageGroup()->preferences(); - wkPrefs->setDeviceWidth(viewportSize.width()); - wkPrefs->setDeviceHeight(viewportSize.height()); - // Let the WebProcess know about the new viewport size, so that // it can resize the content accordingly. m_webPageProxy->setViewportSize(viewportSize); @@ -736,7 +736,7 @@ void QtViewportInteractionEngine::viewportItemSizeChanged() informVisibleContentChange(QPointF()); } -void QtViewportInteractionEngine::scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale) +void QtViewportHandler::scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale) { QPointF oldPinchCenterOnViewport = m_viewportItem->mapFromWebContent(centerInCSSCoordinates); m_pageItem->setContentsScale(itemScaleFromCSS(cssScale)); @@ -747,6 +747,6 @@ void QtViewportInteractionEngine::scaleContent(const QPointF& centerInCSSCoordin } // namespace WebKit -#include "moc_QtViewportInteractionEngine.cpp" +#include "moc_QtViewportHandler.cpp" diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportHandler.h index b25c160c8..e4a8c51fb 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h +++ b/Source/WebKit2/UIProcess/qt/QtViewportHandler.h @@ -19,8 +19,8 @@ * */ -#ifndef QtViewportInteractionEngine_h -#define QtViewportInteractionEngine_h +#ifndef QtViewportHandler_h +#define QtViewportHandler_h #include <QtCore/QObject> #include <QtCore/QRectF> @@ -43,12 +43,12 @@ namespace WebKit { class WebPageProxy; class ViewportUpdateDeferrer; -class QtViewportInteractionEngine : public QObject { +class QtViewportHandler : public QObject { Q_OBJECT public: - QtViewportInteractionEngine(WebPageProxy*, QQuickWebView*, QQuickWebPage*); - ~QtViewportInteractionEngine(); + QtViewportHandler(WebPageProxy*, QQuickWebView*, QQuickWebPage*); + ~QtViewportHandler(); void touchBegin(); void touchEnd(); @@ -107,6 +107,8 @@ private: qreal innerBoundedCSSScale(qreal) const; qreal outerBoundedCSSScale(qreal) const; + void setInitialScaleIfNeeded(); + void setCSSScale(qreal); qreal currentCSSScale() const; @@ -114,6 +116,7 @@ private: void animatePageItemRectVisible(const QRectF&); QRect visibleContentsRect() const; + QRectF initialRect() const; QRectF nearestValidBounds() const; QRectF computePosRangeForPageItemAtScale(qreal itemScale) const; @@ -172,4 +175,4 @@ private: } // namespace WebKit -#endif // QtViewportInteractionEngine_h +#endif // QtViewportHandler_h diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp index 5132c7939..592bb371c 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp @@ -89,11 +89,8 @@ QImage QtWebIconDatabaseClient::iconImageForPageURL(const WTF::String& pageURL, MutexLocker locker(m_imageLock); WebCore::IntSize size(iconSize.width(), iconSize.height()); - RefPtr<WebCore::Image> image = m_iconDatabase->imageForPageURL(pageURL, size); - if (!image) - return QImage(); - QPixmap* nativeImage = image->nativeImageForCurrentFrame(); + QPixmap* nativeImage = m_iconDatabase->nativeImageForPageURL(pageURL, size); if (!nativeImage) return QImage(); diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp index bbdc3a63b..4f131ccdf 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp @@ -24,7 +24,7 @@ #include "NativeWebKeyboardEvent.h" #include "NativeWebMouseEvent.h" #include "NativeWebWheelEvent.h" -#include "QtViewportInteractionEngine.h" +#include "QtViewportHandler.h" #include "WebPageProxy.h" #include "qquickwebpage_p.h" #include "qquickwebview_p.h" @@ -89,7 +89,7 @@ static inline WebCore::DragOperation dropActionToDragOperation(Qt::DropActions a QtWebPageEventHandler::QtWebPageEventHandler(WKPageRef pageRef, QQuickWebPage* qmlWebPage, QQuickWebView* qmlWebView) : m_webPageProxy(toImpl(pageRef)) - , m_interactionEngine(0) + , m_viewportHandler(0) , m_panGestureRecognizer(this) , m_pinchGestureRecognizer(this) , m_tapGestureRecognizer(this) @@ -98,6 +98,7 @@ QtWebPageEventHandler::QtWebPageEventHandler(WKPageRef pageRef, QQuickWebPage* q , m_previousClickButton(Qt::NoButton) , m_clickCount(0) , m_postponeTextInputStateChanged(false) + , m_isTapHighlightActive(false) { connect(qApp->inputPanel(), SIGNAL(visibleChanged()), this, SLOT(inputPanelVisibleChanged())); } @@ -227,23 +228,32 @@ void QtWebPageEventHandler::handleDropEvent(QDropEvent* ev) ev->setAccepted(accepted); } -void QtWebPageEventHandler::handlePotentialSingleTapEvent(const QTouchEvent::TouchPoint& point) +void QtWebPageEventHandler::activateTapHighlight(const QTouchEvent::TouchPoint& point) { #if ENABLE(TOUCH_EVENTS) - if (point.pos() == QPointF()) { - // An empty point deactivates the highlighting. - m_webPageProxy->handlePotentialActivation(IntPoint(), IntSize()); - } else { - QTransform fromItemTransform = m_webPage->transformFromItem(); - m_webPageProxy->handlePotentialActivation(IntPoint(fromItemTransform.map(point.pos()).toPoint()), IntSize(point.rect().size().toSize())); - } + ASSERT(!point.pos().toPoint().isNull()); + ASSERT(!m_isTapHighlightActive); + m_isTapHighlightActive = true; + QTransform fromItemTransform = m_webPage->transformFromItem(); + m_webPageProxy->handlePotentialActivation(IntPoint(fromItemTransform.map(point.pos()).toPoint()), IntSize(point.rect().size().toSize())); #else Q_UNUSED(point); #endif } +void QtWebPageEventHandler::deactivateTapHighlight() +{ + if (!m_isTapHighlightActive) + return; + + // An empty point deactivates the highlighting. + m_webPageProxy->handlePotentialActivation(IntPoint(), IntSize()); + m_isTapHighlightActive = false; +} + void QtWebPageEventHandler::handleSingleTapEvent(const QTouchEvent::TouchPoint& point) { + deactivateTapHighlight(); m_postponeTextInputStateChanged = true; QTransform fromItemTransform = m_webPage->transformFromItem(); @@ -253,6 +263,7 @@ void QtWebPageEventHandler::handleSingleTapEvent(const QTouchEvent::TouchPoint& void QtWebPageEventHandler::handleDoubleTapEvent(const QTouchEvent::TouchPoint& point) { + deactivateTapHighlight(); QTransform fromItemTransform = m_webPage->transformFromItem(); m_webPageProxy->findZoomableAreaForPoint(fromItemTransform.map(point.pos()).toPoint(), IntSize(point.rect().size().toSize())); } @@ -286,9 +297,9 @@ void QtWebPageEventHandler::handleFocusOutEvent(QFocusEvent*) m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive); } -void QtWebPageEventHandler::setViewportInteractionEngine(QtViewportInteractionEngine* engine) +void QtWebPageEventHandler::setViewportHandler(QtViewportHandler* handler) { - m_interactionEngine = engine; + m_viewportHandler = handler; } void QtWebPageEventHandler::handleInputMethodEvent(QInputMethodEvent* ev) @@ -387,7 +398,7 @@ static void setInputPanelVisible(bool visible) void QtWebPageEventHandler::inputPanelVisibleChanged() { - if (!m_interactionEngine) + if (!m_viewportHandler) return; // We only respond to the input panel becoming visible. @@ -396,7 +407,7 @@ void QtWebPageEventHandler::inputPanelVisibleChanged() const EditorState& editor = m_webPageProxy->editorState(); if (editor.isContentEditable) - m_interactionEngine->focusEditableArea(QRectF(editor.cursorRect), QRectF(editor.editorRect)); + m_viewportHandler->focusEditableArea(QRectF(editor.cursorRect), QRectF(editor.editorRect)); } void QtWebPageEventHandler::updateTextInputState() @@ -432,7 +443,7 @@ void QtWebPageEventHandler::doneWithGestureEvent(const WebGestureEvent& event, b #if ENABLE(TOUCH_EVENTS) void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) { - if (!m_interactionEngine) + if (!m_viewportHandler) return; if (wasEventHandled || event.type() == WebEvent::TouchCancel) { @@ -447,9 +458,9 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, switch (ev->type()) { case QEvent::TouchBegin: - ASSERT(!m_interactionEngine->panGestureActive()); - ASSERT(!m_interactionEngine->pinchGestureActive()); - m_interactionEngine->touchBegin(); + ASSERT(!m_viewportHandler->panGestureActive()); + ASSERT(!m_viewportHandler->pinchGestureActive()); + m_viewportHandler->touchBegin(); // The interaction engine might still be animating kinetic scrolling or a scale animation // such as double-tap to zoom or the bounce back effect. A touch stops the kinetic scrolling @@ -458,11 +469,11 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, break; case QEvent::TouchUpdate: // The scale animation can only be interrupted by a pinch gesture, which will then take over. - if (m_interactionEngine->scaleAnimationActive() && m_pinchGestureRecognizer.isRecognized()) - m_interactionEngine->interruptScaleAnimation(); + if (m_viewportHandler->scaleAnimationActive() && m_pinchGestureRecognizer.isRecognized()) + m_viewportHandler->interruptScaleAnimation(); break; case QEvent::TouchEnd: - m_interactionEngine->touchEnd(); + m_viewportHandler->touchEnd(); break; default: break; @@ -470,7 +481,7 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, // If the scale animation is active we don't pass the event to the recognizers. In the future // we would want to queue the event here and repost then when the animation ends. - if (m_interactionEngine->scaleAnimationActive()) + if (m_viewportHandler->scaleAnimationActive()) return; const QList<QTouchEvent::TouchPoint>& touchPoints = ev->touchPoints(); @@ -489,9 +500,14 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, if (!activeTouchPointCount) { if (touchPointCount == 1) { // No active touch points, one finger released. - if (!m_panGestureRecognizer.isRecognized()) - m_tapGestureRecognizer.update(ev->type(), touchPoints.first()); - m_panGestureRecognizer.finish(touchPoints.first(), eventTimestampMillis); + if (m_panGestureRecognizer.isRecognized()) + m_panGestureRecognizer.finish(touchPoints.first(), eventTimestampMillis); + else { + // The events did not result in a pan gesture. + m_panGestureRecognizer.cancel(); + m_tapGestureRecognizer.finish(touchPoints.first()); + } + } else m_pinchGestureRecognizer.finish(); @@ -511,18 +527,18 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, if (m_panGestureRecognizer.isRecognized() || m_pinchGestureRecognizer.isRecognized() || m_webView->isMoving()) m_tapGestureRecognizer.cancel(); else if (touchPointCount == 1) - m_tapGestureRecognizer.update(ev->type(), touchPoints.first()); + m_tapGestureRecognizer.update(touchPoints.first()); } #endif void QtWebPageEventHandler::didFindZoomableArea(const IntPoint& target, const IntRect& area) { - if (!m_interactionEngine) + if (!m_viewportHandler) return; // FIXME: As the find method might not respond immediately during load etc, // we should ignore all but the latest request. - m_interactionEngine->zoomToAreaGestureEnded(QPointF(target), QRectF(area)); + m_viewportHandler->zoomToAreaGestureEnded(QPointF(target), QRectF(area)); } void QtWebPageEventHandler::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage) diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h index 74acdb77e..b64f6fee6 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h @@ -46,7 +46,7 @@ class IntRect; namespace WebKit { class NativeWebTouchEvent; -class QtViewportInteractionEngine; +class QtViewportHandler; class ShareableBitmap; class WebGestureEvent; class WebPageProxy; @@ -75,9 +75,10 @@ public: void handleInputMethodEvent(QInputMethodEvent*); void handleTouchEvent(QTouchEvent*); - void setViewportInteractionEngine(QtViewportInteractionEngine*); + void setViewportHandler(QtViewportHandler*); - void handlePotentialSingleTapEvent(const QTouchEvent::TouchPoint&); + void activateTapHighlight(const QTouchEvent::TouchPoint&); + void deactivateTapHighlight(); void handleSingleTapEvent(const QTouchEvent::TouchPoint&); void handleDoubleTapEvent(const QTouchEvent::TouchPoint&); @@ -89,13 +90,13 @@ public: #endif void resetGestureRecognizers(); - QtViewportInteractionEngine* interactionEngine() { return m_interactionEngine; } + QtViewportHandler* viewportHandler() { return m_viewportHandler; } void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage); protected: WebPageProxy* m_webPageProxy; - QtViewportInteractionEngine* m_interactionEngine; + QtViewportHandler* m_viewportHandler; QtPanGestureRecognizer m_panGestureRecognizer; QtPinchGestureRecognizer m_pinchGestureRecognizer; QtTapGestureRecognizer m_tapGestureRecognizer; @@ -113,6 +114,7 @@ private: Qt::MouseButton m_previousClickButton; int m_clickCount; bool m_postponeTextInputStateChanged; + bool m_isTapHighlightActive; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/qt/WebContextQt.cpp b/Source/WebKit2/UIProcess/qt/WebContextQt.cpp index 5da97cb12..3f38dd288 100644 --- a/Source/WebKit2/UIProcess/qt/WebContextQt.cpp +++ b/Source/WebKit2/UIProcess/qt/WebContextQt.cpp @@ -29,36 +29,33 @@ #include "ApplicationCacheStorage.h" #include "FileSystem.h" +#include "QtDefaultDataLocation.h" #include "WKSharedAPICast.h" #if ENABLE(GEOLOCATION) #include "WebGeolocationProviderQt.h" #endif #include "WebProcessCreationParameters.h" #include <QCoreApplication> -#include <QStandardPaths> #include <QDir> #include <QProcess> namespace WebKit { -static QString defaultDataLocation() +static QString s_defaultDatabaseDirectory; +static QString s_defaultLocalStorageDirectory; + +static String defaultDiskCacheDirectory() { - static QString s_dataLocation; + static String s_defaultDiskCacheDirectory; - if (!s_dataLocation.isEmpty()) - return s_dataLocation; + if (!s_defaultDiskCacheDirectory.isEmpty()) + return s_defaultDiskCacheDirectory; - QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - if (dataLocation.isEmpty()) - dataLocation = WebCore::pathByAppendingComponent(QDir::homePath(), QCoreApplication::applicationName()); - s_dataLocation = WebCore::pathByAppendingComponent(dataLocation, ".QtWebKit/"); - WebCore::makeAllDirectories(s_dataLocation); - return s_dataLocation; + s_defaultDiskCacheDirectory = WebCore::pathByAppendingComponent(defaultDataLocation(), "cache/"); + WebCore::makeAllDirectories(s_defaultDiskCacheDirectory); + return s_defaultDiskCacheDirectory; } -static QString s_defaultDatabaseDirectory; -static QString s_defaultLocalStorageDirectory; - String WebContext::applicationCacheDirectory() { return WebCore::cacheStorage().cacheDirectory(); @@ -68,6 +65,7 @@ void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& para { qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); parameters.cookieStorageDirectory = defaultDataLocation(); + parameters.diskCacheDirectory = defaultDiskCacheDirectory(); #if ENABLE(GEOLOCATION) static WebGeolocationProviderQt* location = WebGeolocationProviderQt::create(toAPI(geolocationManagerProxy())); WKGeolocationManagerSetProvider(toAPI(geolocationManagerProxy()), WebGeolocationProviderQt::provider(location)); diff --git a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.cpp b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.cpp index debef4716..be2c6cc66 100644 --- a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.cpp +++ b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.cpp @@ -33,4 +33,10 @@ bool WebSoupRequestManagerClient::didReceiveURIRequest(WebSoupRequestManagerProx return true; } +void WebSoupRequestManagerClient::didFailToLoadURIRequest(WebSoupRequestManagerProxy* soupRequestManager, uint64_t requestID) +{ + if (m_client.didFailToLoadURIRequest) + m_client.didFailToLoadURIRequest(toAPI(soupRequestManager), requestID, m_client.clientInfo); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.h b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.h index afbba7007..dc1755e5a 100644 --- a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.h +++ b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.h @@ -31,6 +31,7 @@ class WebURL; class WebSoupRequestManagerClient : public APIClient<WKSoupRequestManagerClient, kWKSoupRequestManagerClientCurrentVersion> { public: bool didReceiveURIRequest(WebSoupRequestManagerProxy*, WebURL*, uint64_t requestID); + void didFailToLoadURIRequest(WebSoupRequestManagerProxy*, uint64_t requestID); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp index 5123346b5..c766b0adb 100644 --- a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp @@ -33,6 +33,7 @@ PassRefPtr<WebSoupRequestManagerProxy> WebSoupRequestManagerProxy::create(WebCon WebSoupRequestManagerProxy::WebSoupRequestManagerProxy(WebContext* context) : m_webContext(context) + , m_loadFailed(false) { } @@ -68,6 +69,9 @@ void WebSoupRequestManagerProxy::didHandleURIRequest(const WebData* requestData, void WebSoupRequestManagerProxy::didReceiveURIRequestData(const WebData* requestData, uint64_t requestID) { + if (m_loadFailed) + return; + ASSERT(m_webContext); m_webContext->sendToAllProcesses(Messages::WebSoupRequestManager::DidReceiveURIRequestData(requestData->dataReference(), requestID)); } @@ -78,4 +82,10 @@ void WebSoupRequestManagerProxy::didReceiveURIRequest(const String& uriString, u didHandleURIRequest(WebData::create(0, 0).get(), 0, String(), requestID); } +void WebSoupRequestManagerProxy::didFailToLoadURIRequest(uint64_t requestID) +{ + m_loadFailed = true; + m_client.didFailToLoadURIRequest(this, requestID); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h index f43f7ce5c..92bd63e1e 100644 --- a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h +++ b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h @@ -52,6 +52,7 @@ public: void registerURIScheme(const String& scheme); void didHandleURIRequest(const WebData*, uint64_t contentLength, const String& mimeType, uint64_t requestID); void didReceiveURIRequestData(const WebData*, uint64_t requestID); + void didFailToLoadURIRequest(uint64_t requestID); void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); @@ -66,6 +67,7 @@ private: WebContext* m_webContext; WebSoupRequestManagerClient m_client; + bool m_loadFailed; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in index a3d052559..81591a493 100644 --- a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in @@ -22,4 +22,5 @@ messages -> WebSoupRequestManagerProxy { DidReceiveURIRequest(WTF::String uriString, uint64_t requestID); + DidFailToLoadURIRequest(uint64_t requestID); } |