diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API')
86 files changed, 2539 insertions, 880 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h index 0e7175a42..bd3fa2d74 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h +++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h @@ -83,6 +83,8 @@ class WebPageProxy; class WebPluginSiteDataManager; class WebPreferences; class WebProtectionSpace; +class WebRenderLayer; +class WebRenderObject; class WebTextChecker; WK_ADD_API_MAPPING(WKApplicationCacheManagerRef, WebApplicationCacheManagerProxy) @@ -119,6 +121,8 @@ WK_ADD_API_MAPPING(WKPageRef, WebPageProxy) WK_ADD_API_MAPPING(WKPluginSiteDataManagerRef, WebPluginSiteDataManager) WK_ADD_API_MAPPING(WKPreferencesRef, WebPreferences) WK_ADD_API_MAPPING(WKProtectionSpaceRef, WebProtectionSpace) +WK_ADD_API_MAPPING(WKRenderLayerRef, WebRenderLayer) +WK_ADD_API_MAPPING(WKRenderObjectRef, WebRenderObject) WK_ADD_API_MAPPING(WKTextCheckerRef, WebTextChecker) #if ENABLE(INSPECTOR) diff --git a/Source/WebKit2/UIProcess/API/C/WKInspector.cpp b/Source/WebKit2/UIProcess/API/C/WKInspector.cpp index 1a4ecc7c9..7e2187dda 100644 --- a/Source/WebKit2/UIProcess/API/C/WKInspector.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKInspector.cpp @@ -48,6 +48,11 @@ bool WKInspectorIsVisible(WKInspectorRef inspectorRef) return toImpl(inspectorRef)->isVisible(); } +bool WKInspectorIsFront(WKInspectorRef inspectorRef) +{ + return toImpl(inspectorRef)->isFront(); +} + void WKInspectorShow(WKInspectorRef inspectorRef) { toImpl(inspectorRef)->show(); diff --git a/Source/WebKit2/UIProcess/API/C/WKInspector.h b/Source/WebKit2/UIProcess/API/C/WKInspector.h index 2e85688d0..a00d103de 100644 --- a/Source/WebKit2/UIProcess/API/C/WKInspector.h +++ b/Source/WebKit2/UIProcess/API/C/WKInspector.h @@ -43,6 +43,7 @@ WK_EXPORT WKTypeID WKInspectorGetTypeID(); WK_EXPORT WKPageRef WKInspectorGetPage(WKInspectorRef inspector); WK_EXPORT bool WKInspectorIsVisible(WKInspectorRef inspector); +WK_EXPORT bool WKInspectorIsFront(WKInspectorRef inspector); WK_EXPORT void WKInspectorShow(WKInspectorRef inspector); WK_EXPORT void WKInspectorClose(WKInspectorRef inspector); diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp index 634aa9824..5dfcbba29 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp @@ -52,6 +52,11 @@ WKStringRef WKNotificationCopyIconURL(WKNotificationRef notification) return toCopiedAPI(toImpl(notification)->iconURL()); } +WKStringRef WKNotificationCopyReplaceID(WKNotificationRef notification) +{ + return toCopiedAPI(toImpl(notification)->replaceID()); +} + WKSecurityOriginRef WKNotificationGetSecurityOrigin(WKNotificationRef notification) { return toAPI(toImpl(notification)->origin()); diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.h b/Source/WebKit2/UIProcess/API/C/WKNotification.h index 7c2723896..11ea97275 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotification.h +++ b/Source/WebKit2/UIProcess/API/C/WKNotification.h @@ -37,6 +37,7 @@ WK_EXPORT WKTypeID WKNotificationGetTypeID(); WK_EXPORT WKStringRef WKNotificationCopyTitle(WKNotificationRef notification); WK_EXPORT WKStringRef WKNotificationCopyBody(WKNotificationRef notification); WK_EXPORT WKStringRef WKNotificationCopyIconURL(WKNotificationRef notification); +WK_EXPORT WKStringRef WKNotificationCopyReplaceID(WKNotificationRef notification); WK_EXPORT WKSecurityOriginRef WKNotificationGetSecurityOrigin(WKNotificationRef notification); WK_EXPORT uint64_t WKNotificationGetID(WKNotificationRef notification); diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.cpp b/Source/WebKit2/UIProcess/API/C/WKPage.cpp index 3010016c3..130dd0e45 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPage.cpp @@ -660,6 +660,11 @@ void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInf { toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(context, callback)); } + +void WKPageEndPrinting(WKPageRef page) +{ + toImpl(page)->endPrinting(); +} #endif WKImageRef WKPageCreateSnapshotOfVisibleContent(WKPageRef) diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.h b/Source/WebKit2/UIProcess/API/C/WKPage.h index 96d097c60..05b7aff0c 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.h +++ b/Source/WebKit2/UIProcess/API/C/WKPage.h @@ -285,24 +285,29 @@ enum { }; // ContextMenu client -typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKTypeRef userData, const void* clientInfo); +typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo); typedef void (*WKPageCustomContextMenuItemSelectedCallback)(WKPageRef page, WKContextMenuItemRef contextMenuItem, const void* clientInfo); typedef void (*WKPageContextMenuDismissedCallback)(WKPageRef page, const void* clientInfo); +// Deprecated +typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback_deprecatedForUseWithV0)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKTypeRef userData, const void* clientInfo); struct WKPageContextMenuClient { - int version; - const void * clientInfo; - + int version; + const void * clientInfo; + // Version 0 - WKPageGetContextMenuFromProposedContextMenuCallback getContextMenuFromProposedMenu; - WKPageCustomContextMenuItemSelectedCallback customContextMenuItemSelected; - + WKPageGetContextMenuFromProposedContextMenuCallback_deprecatedForUseWithV0 getContextMenuFromProposedMenu_deprecatedForUseWithV0; + WKPageCustomContextMenuItemSelectedCallback customContextMenuItemSelected; + // Version 1 - WKPageContextMenuDismissedCallback contextMenuDismissed; + WKPageContextMenuDismissedCallback contextMenuDismissed; + + // Version 2 + WKPageGetContextMenuFromProposedContextMenuCallback getContextMenuFromProposedMenu; }; typedef struct WKPageContextMenuClient WKPageContextMenuClient; -enum { kWKPageContextMenuClientCurrentVersion = 1 }; +enum { kWKPageContextMenuClientCurrentVersion = 2 }; WK_EXPORT WKTypeID WKPageGetTypeID(); diff --git a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h index 097aabfe1..18860fd74 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h @@ -83,6 +83,7 @@ WK_EXPORT void WKPageComputePagesForPrinting(WKPageRef page, WKFrameRef frame, W typedef void (*WKPageDrawToPDFFunction)(WKDataRef data, WKErrorRef error, void* functionContext); WK_EXPORT void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo); WK_EXPORT void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context); +WK_EXPORT void WKPageEndPrinting(WKPageRef page); // FIXME https://bugs.webkit.org/show_bug.cgi?id=66979: Remove this sync call. WK_EXPORT WKImageRef WKPageCreateSnapshotOfVisibleContent(WKPageRef page); diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp index 87d32ed2f..39903bcb5 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp @@ -688,6 +688,16 @@ bool WKPreferencesGetSuppressesIncrementalRendering(WKPreferencesRef preferences return toImpl(preferencesRef)->suppressesIncrementalRendering(); } +void WKPreferencesSetSuppressIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled) +{ + WKPreferencesSetSuppressesIncrementalRendering(preferencesRef, enabled); +} + +bool WKPreferencesGetSuppressIncrementalRendering(WKPreferencesRef preferencesRef) +{ + return WKPreferencesGetSuppressesIncrementalRendering(preferencesRef); +} + void WKPreferencesSetBackspaceKeyNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled) { toImpl(preferencesRef)->setBackspaceKeyNavigationEnabled(enabled); diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.h b/Source/WebKit2/UIProcess/API/C/WKPreferences.h index 8054e00f3..501c5a5d6 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.h +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.h @@ -172,6 +172,11 @@ WK_EXPORT bool WKPreferencesGetWebAudioEnabled(WKPreferencesRef preferencesRef); // Defaults to false WK_EXPORT void WKPreferencesSetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef); + +// Defaults to false +// These functions are deprecated. See <rdar://problem/10929617> Remove WKPreferences[Get|Set]SuppressIncrementalRendering from WKPreferences.h. +WK_EXPORT void WKPreferencesSetSuppressIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetSuppressIncrementalRendering(WKPreferencesRef preferencesRef); // Defaults to true WK_EXPORT void WKPreferencesSetBackspaceKeyNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled); diff --git a/Source/WebKit2/UIProcess/API/C/mac/WKInspectorMac.h b/Source/WebKit2/UIProcess/API/C/mac/WKInspectorPrivateMac.h index ec5a35afb..aef86a5d9 100644 --- a/Source/WebKit2/UIProcess/API/C/mac/WKInspectorMac.h +++ b/Source/WebKit2/UIProcess/API/C/mac/WKInspectorPrivateMac.h @@ -23,8 +23,8 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKInspectorMac_h -#define WKInspectorMac_h +#ifndef WKInspectorPrivateMac_h +#define WKInspectorPrivateMac_h #ifdef __cplusplus extern "C" { @@ -32,8 +32,18 @@ extern "C" { const NSInteger WKInspectorViewTag = 1000; +// This class is the Web Inspector window delegate. It can be used to add interface +// actions that need to work when the Web Inspector window is key. +WK_EXPORT @interface WKWebInspectorProxyObjCAdapter : NSObject <NSWindowDelegate> { + void* _inspectorProxy; +} + +@property (readonly) WKInspectorRef inspectorRef; + +@end + #ifdef __cplusplus } #endif -#endif // WKInspectorMac_h +#endif // WKInspectorPrivateMac_h diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp index a56265adb..c21162903 100644 --- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp @@ -213,6 +213,11 @@ void PageClientImpl::exitAcceleratedCompositingMode() { notImplemented(); } + +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) +{ + notImplemented(); +} #endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::didChangeScrollbarsForMainFrame() const diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h index 2522153d4..40af3b23f 100644 --- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h @@ -85,6 +85,7 @@ private: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif virtual void didChangeScrollbarsForMainFrame() const; diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp index c3ad3f764..9fadbeab5 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp @@ -242,6 +242,11 @@ void PageClientImpl::exitAcceleratedCompositingMode() { notImplemented(); } + +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) +{ + notImplemented(); +} #endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::didCommitLoadForMainFrame(bool useCustomRepresentation) diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h index 291ba212b..6a1cb2459 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h @@ -92,6 +92,7 @@ private: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif virtual void didCommitLoadForMainFrame(bool useCustomRepresentation); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h index 8c3eec2a4..96bcb4ea2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h @@ -33,6 +33,8 @@ #include <glib.h> typedef struct _WebKitPrintOperation WebKitPrintOperation; +typedef struct _WebKitFindController WebKitFindController; +typedef struct _WebKitWebView WebKitWebView; #ifdef G_OS_WIN32 # ifdef BUILDING_WEBKIT diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp index 4d4eba18d..018f08d3d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp @@ -169,18 +169,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * This signal is emitted after response is received, * every time new data has been written to the destination. It's * useful to know the progress of the download operation. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[RECEIVED_DATA] = g_signal_new("received-data", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, received_data), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__UINT64, - G_TYPE_BOOLEAN, 1, + 0, 0, 0, + webkit_marshal_VOID__UINT64, + G_TYPE_NONE, 1, G_TYPE_UINT64); /** @@ -189,18 +185,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * * This signal is emitted when download finishes successfully or due to an error. * In case of errors #WebKitDownload::failed signal is emitted before this one. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[FINISHED] = g_signal_new("finished", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, finished), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); + 0, 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); /** * WebKitDownload::failed: @@ -213,18 +205,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * with webkit_download_cancel(), this signal is emitted with error * %WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER. The download operation finishes * after an error and #WebKitDownload::finished signal is emitted after this one. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[FAILED] = g_signal_new("failed", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, failed), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__POINTER, - G_TYPE_BOOLEAN, 1, + 0, 0, 0, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); /** @@ -258,17 +246,13 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * This signal is emitted after #WebKitDownload::decide-destination and before * #WebKitDownload::received-data to notify that destination file has been * created successfully at @destination. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[CREATED_DESTINATION] = g_signal_new("created-destination", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, created_destination), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__STRING, + 0, 0, 0, + g_cclosure_marshal_VOID__STRING, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); @@ -304,8 +288,7 @@ void webkitDownloadNotifyProgress(WebKitDownload* download, guint64 bytesReceive download->priv->timer.set(g_timer_new()); priv->currentSize += bytesReceived; - gboolean returnValue; - g_signal_emit(download, signals[RECEIVED_DATA], 0, bytesReceived, &returnValue); + g_signal_emit(download, signals[RECEIVED_DATA], 0, bytesReceived); // Throttle progress notification to not consume high amounts of // CPU on fast links, except when the last notification occured @@ -333,9 +316,9 @@ void webkitDownloadFailed(WebKitDownload* download, const ResourceError& resourc resourceError.localizedDescription().utf8().data())); if (download->priv->timer) g_timer_stop(download->priv->timer.get()); - gboolean returnValue; - g_signal_emit(download, signals[FAILED], 0, webError.get(), &returnValue); - g_signal_emit(download, signals[FINISHED], 0, &returnValue); + + g_signal_emit(download, signals[FAILED], 0, webError.get()); + g_signal_emit(download, signals[FINISHED], 0, NULL); } void webkitDownloadCancelled(WebKitDownload* download) @@ -356,8 +339,7 @@ void webkitDownloadFinished(WebKitDownload* download) } if (download->priv->timer) g_timer_stop(download->priv->timer.get()); - gboolean returnValue; - g_signal_emit(download, signals[FINISHED], 0, &returnValue); + g_signal_emit(download, signals[FINISHED], 0, NULL); } CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h index e200fec53..b6c51fea5 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h @@ -50,15 +50,8 @@ struct _WebKitDownload { struct _WebKitDownloadClass { GObjectClass parent_class; - gboolean (* received_data) (WebKitDownload *download, - guint64 data_length); - gboolean (* finished) (WebKitDownload *download); - gboolean (* failed) (WebKitDownload *download, - GError *error); gboolean (* decide_destination) (WebKitDownload *download, const gchar *suggested_filename); - gboolean (* created_destination) (WebKitDownload *download, - const gchar *destination); }; WEBKIT_API GType diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp new file mode 100644 index 000000000..360137e16 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp @@ -0,0 +1,475 @@ +/* + * 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 "WebKitFindController.h" + +#include "WebKitEnumTypes.h" +#include "WebKitPrivate.h" +#include "WebKitWebViewBasePrivate.h" +#include <glib/gi18n-lib.h> +#include <wtf/gobject/GRefPtr.h> +#include <wtf/text/CString.h> + +using namespace WebCore; + +enum { + FOUND_TEXT, + FAILED_TO_FIND_TEXT, + COUNTED_MATCHES, + + LAST_SIGNAL +}; + +enum { + PROP_0, + + PROP_TEXT, + PROP_OPTIONS, + PROP_MAX_MATCH_COUNT, + PROP_WEB_VIEW +}; + +typedef enum { + FindOperation, + CountOperation +} WebKitFindControllerOperation; + +struct _WebKitFindControllerPrivate { + CString searchText; + uint32_t findOptions; + unsigned maxMatchCount; + WebKitWebView* webView; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE(WebKitFindController, webkit_find_controller, G_TYPE_OBJECT) + +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, kWKFindOptionsCaseInsensitive); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, kWKFindOptionsAtWordStarts); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, kWKFindOptionsTreatMedialCapitalAsWordStart); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_BACKWARDS, kWKFindOptionsBackwards); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_WRAP_AROUND, kWKFindOptionsWrapAround); + +static void didFindString(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +{ + g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FOUND_TEXT], 0, matchCount); +} + +static void didFailToFindString(WKPageRef page, WKStringRef string, const void* clientInfo) +{ + g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FAILED_TO_FIND_TEXT], 0); +} + +static void didCountStringMatches(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +{ + g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[COUNTED_MATCHES], 0, matchCount); +} + +static void webkit_find_controller_init(WebKitFindController* findController) +{ + WebKitFindControllerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(findController, WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerPrivate); + findController->priv = priv; + new (priv) WebKitFindControllerPrivate(); +} + +static WKPageRef inline getWKPageFromWebKitWebView(WebKitWebView* webView) +{ + return toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); +} + +static void webkitFindControllerConstructed(GObject* object) +{ + WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object); + WKPageFindClient wkFindClient = { + kWKPageFindClientCurrentVersion, + findController, // clientInfo + didFindString, + didFailToFindString, + didCountStringMatches + }; + + WKPageSetPageFindClient(getWKPageFromWebKitWebView(findController->priv->webView), &wkFindClient); +} + +static void webkitFindControllerGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object); + + switch (propId) { + case PROP_TEXT: + g_value_set_string(value, webkit_find_controller_get_search_text(findController)); + break; + case PROP_OPTIONS: + g_value_set_uint(value, webkit_find_controller_get_options(findController)); + break; + case PROP_MAX_MATCH_COUNT: + g_value_set_uint(value, webkit_find_controller_get_max_match_count(findController)); + break; + case PROP_WEB_VIEW: + g_value_set_object(value, webkit_find_controller_get_web_view(findController)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitFindControllerSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object); + + switch (propId) { + case PROP_WEB_VIEW: + findController->priv->webView = WEBKIT_WEB_VIEW(g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitFindControllerFinalize(GObject* object) +{ + WEBKIT_FIND_CONTROLLER(object)->priv->~WebKitFindControllerPrivate(); + G_OBJECT_CLASS(webkit_find_controller_parent_class)->finalize(object); +} + +static void webkit_find_controller_class_init(WebKitFindControllerClass* findClass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass); + + gObjectClass->constructed = webkitFindControllerConstructed; + gObjectClass->get_property = webkitFindControllerGetProperty; + gObjectClass->set_property = webkitFindControllerSetProperty; + gObjectClass->finalize = webkitFindControllerFinalize; + + g_type_class_add_private(findClass, sizeof(WebKitFindControllerPrivate)); + + /** + * WebKitFindController:text: + * + * The current search text for this #WebKitFindController. + */ + g_object_class_install_property(gObjectClass, + PROP_TEXT, + g_param_spec_string("text", + _("Search text"), + _("Text to search for in the view"), + 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitFindController:options: + * + * The options to be used in the search operation. + */ + g_object_class_install_property(gObjectClass, + PROP_OPTIONS, + g_param_spec_flags("options", + _("Search Options"), + _("Search options to be used in the search operation"), + WEBKIT_TYPE_FIND_OPTIONS, + WEBKIT_FIND_OPTIONS_NONE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitFindController:max-match-count: + * + * The maximum number of matches to report for a given search. + */ + g_object_class_install_property(gObjectClass, + PROP_MAX_MATCH_COUNT, + g_param_spec_uint("max-match-count", + _("Maximum matches count"), + _("The maximum number of matches in a given text to report"), + 0, G_MAXUINT, 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitFindController:web-view: + * + * The #WebKitWebView this controller is associated to. + */ + g_object_class_install_property(gObjectClass, + PROP_WEB_VIEW, + g_param_spec_object("web-view", + _("WebView"), + _("The WebView associated with this find controller"), + WEBKIT_TYPE_WEB_VIEW, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitFindController::found-text: + * @find_controller: the #WebKitFindController + * @match_count: the number of matches found of the search text + * + * This signal is emitted when a given text is found in the web + * page text. It will be issued if the text is found + * asynchronously after a call to webkit_find_controller_search(), + * webkit_find_controller_search_next() or + * webkit_find_controller_search_previous(). + */ + signals[FOUND_TEXT] = + g_signal_new("found-text", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + /** + * WebKitFindController::failed-to-find-text: + * @find_controller: the #WebKitFindController + * + * This signal is emitted when a search operation does not find + * any result for the given text. It will be issued if the text + * is not found asynchronously after a call to + * webkit_find_controller_search(), webkit_find_controller_search_next() + * or webkit_find_controller_search_previous(). + */ + signals[FAILED_TO_FIND_TEXT] = + g_signal_new("failed-to-find-text", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * WebKitFindController::counted-matches: + * @find_controller: the #WebKitFindController + * @match_count: the number of matches of the search text + * + * This signal is emitted when the #WebKitFindController has + * counted the number of matches for a given text after a call + * to webkit_find_controller_count_matches(). + */ + signals[COUNTED_MATCHES] = + g_signal_new("counted-matches", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); +} + +/** + * webkit_find_controller_get_search_text: + * @find_controller: the #WebKitFindController + * + * Gets the text that @find_controller is currently searching + * for. This text is passed to either + * webkit_find_controller_search() or + * webkit_find_controller_count_matches(). + * + * Returns: the text to look for in the #WebKitWebView. + */ +const char* webkit_find_controller_get_search_text(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0); + + return findController->priv->searchText.data(); +} + +/** + * webkit_find_controller_get_options: + * @find_controller: the #WebKitFindController + * + * Gets a bitmask containing the #WebKitFindOptions associated with + * the current search. + * + * Returns: a bitmask containing the #WebKitFindOptions associated + * with the current search. + */ +guint32 webkit_find_controller_get_options(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), WEBKIT_FIND_OPTIONS_NONE); + + return findController->priv->findOptions; +} + +/** + * webkit_find_controller_get_max_match_count: + * @find_controller: the #WebKitFindController + * + * Gets the maximum number of matches to report during a text + * lookup. This number is passed as the last argument of + * webkit_find_controller_search() or + * webkit_find_controller_count_matches(). + * + * Returns: the maximum number of matches to report. + */ +guint webkit_find_controller_get_max_match_count(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0); + + return findController->priv->maxMatchCount; +} + +/** + * webkit_find_controller_get_web_view: + * @find_controller: the #WebKitFindController + * + * Gets the #WebKitWebView this find controller is associated to. Do + * not unref the returned instance as it belongs to the + * #WebKitFindController. + * + * Returns: (transfer none): the #WebKitWebView. + */ +WebKitWebView* webkit_find_controller_get_web_view(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0); + + return findController->priv->webView; +} + +static void webKitFindControllerPerform(WebKitFindController* findController, WebKitFindControllerOperation operation) +{ + WKFindOptions wkFindOptions = static_cast<WKFindOptions>(findController->priv->findOptions); + WKRetainPtr<WKStringRef> wkSearchText(AdoptWK, WKStringCreateWithUTF8CString(findController->priv->searchText.data())); + WKPageRef wkPage = getWKPageFromWebKitWebView(findController->priv->webView); + + if (operation == FindOperation) { + // Unconditionally highlight text matches. WK1 API was forcing + // clients to enable/disable highlighting. Since most of them + // (all?) where using highlighting we decided to simplify the + // WK2 API and unconditionally show highlights. + wkFindOptions = static_cast<WKFindOptions>(findController->priv->findOptions | kWKFindOptionsShowHighlight); + WKPageFindString(wkPage, wkSearchText.get(), wkFindOptions, findController->priv->maxMatchCount); + return; + } + + WKPageCountStringMatches(wkPage, wkSearchText.get(), wkFindOptions, findController->priv->maxMatchCount); +} + +static inline void webKitFindControllerSetSearchData(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount) +{ + findController->priv->searchText = searchText; + findController->priv->findOptions = findOptions; + findController->priv->maxMatchCount = maxMatchCount; +} + +/** + * webkit_find_controller_search: + * @find_controller: the #WebKitFindController + * @search_text: the text to look for + * @find_options: a bitmask with the #WebKitFindOptions used in the search + * @max_match_count: the maximum number of matches allowed in the search + * + * Looks for @search_text in the #WebKitWebView associated with + * @find_controller since the beginning of the document highlighting + * up to @max_match_count matches. The outcome of the search will be + * asynchronously provided by the #WebKitFindController::found-text + * and #WebKitFindController::failed-to-find-text signals. + * + * To look for the next or previous occurrences of the same text + * with the same find options use webkit_find_controller_search_next() + * and/or webkit_find_controller_search_previous(). The + * #WebKitFindController will use the same text and options for the + * following searches unless they are modified by another call to this + * method. + * + * Note that if the number of matches is higher than @max_match_count + * then #WebKitFindController::found-text will report %G_MAXUINT matches + * instead of the actual number. + * + * Callers should call webkit_find_controller_search_finish() to + * finish the current search operation. + */ +void webkit_find_controller_search(WebKitFindController* findController, const gchar* searchText, guint findOptions, guint maxMatchCount) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + g_return_if_fail(searchText); + + webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerPerform(findController, FindOperation); +} + +/** + * webkit_find_controller_search_next: + * @find_controller: the #WebKitFindController + * + * Looks for the next occurrence of the search text. + * + * Calling this method before webkit_find_controller_search() or + * webkit_find_controller_count_matches() is a programming error. + */ +void webkit_find_controller_search_next(WebKitFindController* findController) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + + findController->priv->findOptions = findController->priv->findOptions & ~WEBKIT_FIND_OPTIONS_BACKWARDS; + webKitFindControllerPerform(findController, FindOperation); +} + +/** + * webkit_find_controller_search_previous: + * @find_controller: the #WebKitFindController + * + * Looks for the previous occurrence of the search text. + * + * Calling this method before webkit_find_controller_search() or + * webkit_find_controller_count_matches() is a programming error. + */ +void webkit_find_controller_search_previous(WebKitFindController* findController) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + + findController->priv->findOptions = findController->priv->findOptions | WEBKIT_FIND_OPTIONS_BACKWARDS; + webKitFindControllerPerform(findController, FindOperation); +} + +/** + * webkit_find_controller_count_matches: + * @find_controller: the #WebKitFindController + * @search_text: the text to look for + * @find_options: a bitmask with the #WebKitFindOptions used in the search + * @max_match_count: the maximum number of matches allowed in the search + * + * Counts the number of matches for @search_text found in the + * #WebKitWebView with the provided @find_options. The number of + * matches will be provided by the + * #WebKitFindController::counted-matches signal. + */ +void webkit_find_controller_count_matches(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + g_return_if_fail(searchText); + + webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerPerform(findController, CountOperation); +} + +/** + * webkit_find_controller_search_finish: + * @find_controller: a #WebKitFindController + * + * Finishes a find operation started by + * webkit_find_controller_search(). It will basically unhighlight + * every text match found. + * + * This method will be typically called when the search UI is + * closed/hidden by the client application. + */ +void webkit_find_controller_search_finish(WebKitFindController* findController) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + + WKPageHideFindUI(getWKPageFromWebKitWebView(findController->priv->webView)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h new file mode 100644 index 000000000..3a47f99d4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h @@ -0,0 +1,116 @@ +/* + * 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. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitFindController_h +#define WebKitFindController_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_FIND_CONTROLLER (webkit_find_controller_get_type()) +#define WEBKIT_FIND_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindController)) +#define WEBKIT_FIND_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerClass)) +#define WEBKIT_IS_FIND_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_FIND_CONTROLLER)) +#define WEBKIT_IS_FIND_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_FIND_CONTROLLER)) +#define WEBKIT_FIND_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerClass)) + +typedef struct _WebKitFindControllerPrivate WebKitFindControllerPrivate; +typedef struct _WebKitFindControllerClass WebKitFindControllerClass; + +/** + * WebKitFindOptions: + * @WEBKIT_FIND_OPTIONS_NONE: no search flags, this means a case + * sensitive, no wrap, forward only search. + * @WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE: case insensitive search. + * @WEBKIT_FIND_OPTIONS_AT_WORD_STARTS: search text only at the + * begining of the words. + * @WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START: treat + * capital letters in the middle of words as word start. + * @WEBKIT_FIND_OPTIONS_BACKWARDS: search backwards. + * @WEBKIT_FIND_OPTIONS_WRAP_AROUND: if not present search will stop + * at the end of the document. + * + * Enum values used to specify search options. + */ +typedef enum { + WEBKIT_FIND_OPTIONS_NONE, + + WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE = 1 << 0, + WEBKIT_FIND_OPTIONS_AT_WORD_STARTS = 1 << 1, + WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START = 1 << 2, + WEBKIT_FIND_OPTIONS_BACKWARDS = 1 << 3, + WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4, +} WebKitFindOptions; + +struct _WebKitFindController { + GObject parent; + + /*< private >*/ + WebKitFindControllerPrivate *priv; +}; + +struct _WebKitFindControllerClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_find_controller_get_type (void); + +WEBKIT_API void +webkit_find_controller_search (WebKitFindController *find_controller, + const gchar *search_text, + guint32 find_options, + guint max_match_count); + +WEBKIT_API void +webkit_find_controller_search_finish (WebKitFindController *find_controller); + +WEBKIT_API void +webkit_find_controller_search_next (WebKitFindController *find_controller); + +WEBKIT_API void +webkit_find_controller_search_previous (WebKitFindController *find_controller); + +WEBKIT_API void +webkit_find_controller_count_matches (WebKitFindController *find_controller, + const gchar *search_text, + guint32 find_options, + guint max_match_count); + +WEBKIT_API const gchar * +webkit_find_controller_get_search_text (WebKitFindController *find_controller); + +WEBKIT_API guint32 +webkit_find_controller_get_options (WebKitFindController *find_controller); + +WEBKIT_API guint +webkit_find_controller_get_max_match_count (WebKitFindController *find_controller); + +WEBKIT_API WebKitWebView * +webkit_find_controller_get_web_view (WebKitFindController *find_controller); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp index 94d13eab2..e40fde76e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp @@ -38,7 +38,7 @@ using namespace WebKit; * @See_also: #WebKitPolicyDecision, #WebKitWebView * * WebKitNavigationPolicyDecision represents a policy decision for events associated with - * navigations. If the value of WebKitNavigationPolicyDecision:mouse-button is not 0, then + * navigations. If the value of #WebKitNavigationPolicyDecision:mouse-button is not 0, then * the navigation was triggered by a mouse event. */ @@ -143,7 +143,7 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * * If the navigation associated with this policy decision was originally * triggered by a mouse event, this property contains a bitmask of various - * GdkModifierType values describing the modifiers used for that click. + * #GdkModifierType values describing the modifiers used for that click. * If the navigation was not triggered by a mouse event or no modifiers * were active, the value of this property will be zero. */ @@ -248,7 +248,7 @@ WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigation * * Gets the value of the #WebKitNavigationPolicyDecision:frame-name property. * - * Returns: The name of the new frame this navigation action targets or %NULL + * Returns: The name of the new frame this navigation action targets or %NULL */ const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPolicyDecision* decision) { diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp index a20ccb2a6..d79d40149 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp @@ -367,7 +367,7 @@ void webkit_print_operation_set_page_setup(WebKitPrintOperation* printOperation, * the user. This method returns when the print dialog is closed. * If the print dialog is cancelled %WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL * is returned. If the user clicks on the print button, %WEBKIT_PRINT_OPERATION_RESPONSE_PRINT - * is returned and the print operation starts. In this case, the WebKitPrintOperation::finished + * is returned and the print operation starts. In this case, the #WebKitPrintOperation::finished * signal is emitted when the operation finishes. * If the print dialog is not cancelled current print settings and page setup of @print_operation * are updated with options selected by the user when Print button is pressed in print dialog. @@ -394,7 +394,7 @@ WebKitPrintOperationResponse webkit_print_operation_run_dialog(WebKitPrintOperat * are not set with webkit_print_operation_set_print_settings() and * webkit_print_operation_set_page_setup(), the default options will be used * and the print job will be sent to the default printer. - * The WebKitPrintOperation::finished signal is emitted when the printing + * The #WebKitPrintOperation::finished signal is emitted when the printing * operation finishes. */ void webkit_print_operation_print(WebKitPrintOperation* printOperation) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h index 43d26cc85..e785c3638 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h @@ -28,7 +28,9 @@ #include <WebKit2/WKAPICast.h> #include <WebKit2/WKDownload.h> +#include <WebKit2/WKFindOptions.h> #include <WebKit2/WKRetainPtr.h> +#include <WebKit2/WKString.h> #include <WebKit2/WebKit2.h> #include <glib.h> #include <wtf/Assertions.h> diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp new file mode 100644 index 000000000..863665d71 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp @@ -0,0 +1,126 @@ +/* + * 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 "WebKitScriptDialog.h" + +#include "WebKitScriptDialogPrivate.h" + +static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog) +{ + WebKitScriptDialog* copy = g_slice_new0(WebKitScriptDialog); + new (copy) WebKitScriptDialog(dialog); + return copy; +} + +static void webkitScriptDialogFree(WebKitScriptDialog* dialog) +{ + dialog->~WebKitScriptDialog(); + g_slice_free(WebKitScriptDialog, dialog); +} + +G_DEFINE_BOXED_TYPE(WebKitScriptDialog, webkit_script_dialog, webkitScriptDialogCopy, webkitScriptDialogFree) + +/** + * webkit_script_dialog_get_dialog_type: + * @dialog: a #WebKitScriptDialog + * + * Get the dialog type of a #WebKitScriptDialog. + * + * Returns: the #WebKitScriptDialogType of @dialog + */ +WebKitScriptDialogType webkit_script_dialog_get_dialog_type(WebKitScriptDialog* dialog) +{ + g_return_val_if_fail(dialog, WEBKIT_SCRIPT_DIALOG_ALERT); + + return static_cast<WebKitScriptDialogType>(dialog->type); +} + +/** + * webkit_script_dialog_get_message: + * @dialog: a #WebKitScriptDialog + * + * Get the message of a #WebKitScriptDialog. + * + * Returns: the message of @dialog. + */ +const char* webkit_script_dialog_get_message(WebKitScriptDialog* dialog) +{ + g_return_val_if_fail(dialog, 0); + + return dialog->message.data(); +} + +/** + * webkit_script_dialog_confirm_set_confirmed: + * @dialog: a #WebKitScriptDialog + * @confirmed: whether user confirmed the dialog + * + * This method is used for %WEBKIT_SCRIPT_DIALOG_CONFIRM dialogs when + * #WebKitWebView::script-dialog signal is emitted to set whether the user + * confirmed the dialog or not. The default implementation of #WebKitWebView::script-dialog + * signal sets %TRUE when the OK button is clicked and %FALSE otherwise. + * It's an error to use this method with a #WebKitScriptDialog that is not of type + * %WEBKIT_SCRIPT_DIALOG_CONFIRM. + */ +void webkit_script_dialog_confirm_set_confirmed(WebKitScriptDialog* dialog, gboolean confirmed) +{ + g_return_if_fail(dialog); + g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_CONFIRM); + + dialog->confirmed = confirmed; +} + +/** + * webkit_script_dialog_prompt_get_default_text: + * @dialog: a #WebKitScriptDialog + * + * Get the default text of a #WebKitScriptDialog of type %WEBKIT_SCRIPT_DIALOG_PROMPT. + * It's an error to use this method with a #WebKitScriptDialog that is not of type + * %WEBKIT_SCRIPT_DIALOG_PROMPT. + * + * Returns: the default text of @dialog + */ +const char* webkit_script_dialog_prompt_get_default_text(WebKitScriptDialog* dialog) +{ + g_return_val_if_fail(dialog, 0); + g_return_val_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_PROMPT, 0); + + return dialog->defaultText.data(); +} + +/** + * webkit_script_dialog_prompt_set_text: + * @dialog: a #WebKitScriptDialog + * @text: the text to set + * + * This method is used for %WEBKIT_SCRIPT_DIALOG_PROMPT dialogs when + * #WebKitWebView::script-dialog signal is emitted to set the text + * entered by the user. The default implementation of #WebKitWebView::script-dialog + * signal sets the text of the entry form when OK button is clicked, otherwise %NULL is set. + * It's an error to use this method with a #WebKitScriptDialog that is not of type + * %WEBKIT_SCRIPT_DIALOG_PROMPT. + */ +void webkit_script_dialog_prompt_set_text(WebKitScriptDialog* dialog, const char* text) +{ + g_return_if_fail(dialog); + g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_PROMPT); + + dialog->text = text; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h new file mode 100644 index 000000000..cf88535ad --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h @@ -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. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitScriptDialog_h +#define WebKitScriptDialog_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_SCRIPT_DIALOG (webkit_script_dialog_get_type()) + +typedef struct _WebKitScriptDialog WebKitScriptDialog; + +/** + * WebKitScriptDialogType: + * @WEBKIT_SCRIPT_DIALOG_ALERT: Alert script dialog, used to show a + * message to the user. + * @WEBKIT_SCRIPT_DIALOG_CONFIRM: Confirm script dialog, used to ask + * confirmation to the user. + * @WEBKIT_SCRIPT_DIALOG_PROMPT: Prompt script dialog, used to ask + * information to the user. + * + * Enum values used for determining the type of #WebKitScriptDialog + */ +typedef enum { + WEBKIT_SCRIPT_DIALOG_ALERT, + WEBKIT_SCRIPT_DIALOG_CONFIRM, + WEBKIT_SCRIPT_DIALOG_PROMPT +} WebKitScriptDialogType; + +WEBKIT_API GType +webkit_script_dialog_get_type (void); + +WEBKIT_API WebKitScriptDialogType +webkit_script_dialog_get_dialog_type (WebKitScriptDialog *dialog); + +WEBKIT_API const gchar * +webkit_script_dialog_get_message (WebKitScriptDialog *dialog); + +WEBKIT_API void +webkit_script_dialog_confirm_set_confirmed (WebKitScriptDialog *dialog, + gboolean confirmed); + +WEBKIT_API const gchar * +webkit_script_dialog_prompt_get_default_text (WebKitScriptDialog *dialog); + +WEBKIT_API void +webkit_script_dialog_prompt_set_text (WebKitScriptDialog *dialog, + const gchar *text); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialogPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialogPrivate.h new file mode 100644 index 000000000..5f1a43d94 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialogPrivate.h @@ -0,0 +1,60 @@ +/* + * 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 WebKitScriptDialogPrivate_h +#define WebKitScriptDialogPrivate_h + +#include "WebKitScriptDialog.h" +#include <wtf/text/CString.h> + +struct _WebKitScriptDialog { + _WebKitScriptDialog(unsigned type, const CString& message) + : type(type) + , message(message) + , confirmed(false) + { + } + + _WebKitScriptDialog(unsigned type, const CString& message, const CString& defaultText) + : type(type) + , message(message) + , defaultText(defaultText) + , confirmed(false) + { + ASSERT(type == WEBKIT_SCRIPT_DIALOG_PROMPT); + } + + _WebKitScriptDialog(WebKitScriptDialog* dialog) + : type(dialog->type) + , message(dialog->message) + , defaultText(dialog->defaultText) + , confirmed(dialog->confirmed) + , text(dialog->text) + { + } + + unsigned type; + CString message; + CString defaultText; + + bool confirmed; + CString text; +}; + +#endif // WebKitScriptDialogPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp index c1c4a970b..b4b267d1b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp @@ -46,6 +46,7 @@ struct _WebKitSettingsPrivate { CString fantasyFontFamily; CString pictographFontFamily; CString defaultCharset; + bool zoomTextOnly; }; /** @@ -103,7 +104,8 @@ enum { PROP_ENABLE_FULLSCREEN, PROP_PRINT_BACKGROUNDS, PROP_ENABLE_WEBAUDIO, - PROP_ENABLE_WEBGL + PROP_ENABLE_WEBGL, + PROP_ZOOM_TEXT_ONLY }; static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) @@ -210,6 +212,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu case PROP_ENABLE_WEBGL: webkit_settings_set_enable_webgl(settings, g_value_get_boolean(value)); break; + case PROP_ZOOM_TEXT_ONLY: + webkit_settings_set_zoom_text_only(settings, g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -320,6 +325,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val case PROP_ENABLE_WEBGL: g_value_set_boolean(value, webkit_settings_get_enable_webgl(settings)); break; + case PROP_ZOOM_TEXT_ONLY: + g_value_set_boolean(value, webkit_settings_get_zoom_text_only(settings)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -816,6 +824,22 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) FALSE, readWriteConstructParamFlags)); + /** + * WebKitSettings:zoom-text-only: + * + * Whether #WebKitWebView:zoom-level affects only the + * text of the page or all the contents. Other contents containing text + * like form controls will be also affected by zoom factor when + * this property is enabled. + */ + g_object_class_install_property(gObjectClass, + PROP_ZOOM_TEXT_ONLY, + g_param_spec_boolean("zoom-text-only", + _("Zoom Text Only"), + _("Whether zoom level of web view changes only the text size"), + FALSE, + readWriteConstructParamFlags)); + g_type_class_add_private(klass, sizeof(WebKitSettingsPrivate)); } @@ -2073,3 +2097,39 @@ void webkit_settings_set_enable_webgl(WebKitSettings* settings, gboolean enabled WKPreferencesSetWebGLEnabled(priv->preferences.get(), enabled); g_object_notify(G_OBJECT(settings), "enable-webgl"); } + +/** + * webkit_settings_set_zoom_text_only: + * @settings: a #WebKitSettings + * @zoom_text_only: Value to be set + * + * Set the #WebKitSettings:zoom-text-only property. + */ +void webkit_settings_set_zoom_text_only(WebKitSettings* settings, gboolean zoomTextOnly) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->zoomTextOnly == zoomTextOnly) + return; + + priv->zoomTextOnly = zoomTextOnly; + g_object_notify(G_OBJECT(settings), "zoom-text-only"); +} + +/** + * webkit_settings_get_zoom_text_only: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:zoom-text-only property. + * + * Returns: %TRUE If zoom level of the view should only affect the text + * or %FALSE if all view contents should be scaled. + */ +gboolean webkit_settings_get_zoom_text_only(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->zoomTextOnly; +} + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h index b22ba00ff..25a78aca3 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h @@ -307,6 +307,13 @@ WEBKIT_API void webkit_settings_set_enable_webgl (WebKitSettings *settings, gboolean enabled); +WEBKIT_API void +webkit_settings_set_zoom_text_only (WebKitSettings *settings, + gboolean zoom_text_only); + +WEBKIT_API gboolean +webkit_settings_get_zoom_text_only (WebKitSettings *settings); + G_END_DECLS #endif /* WebKitSettings_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp index be590ff33..4f17d4669 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp @@ -30,6 +30,7 @@ #include "WebKitPolicyClient.h" #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" +#include "WebKitScriptDialogPrivate.h" #include "WebKitSettingsPrivate.h" #include "WebKitUIClient.h" #include "WebKitWebContextPrivate.h" @@ -55,9 +56,7 @@ enum { READY_TO_SHOW, CLOSE, - SCRIPT_ALERT, - SCRIPT_CONFIRM, - SCRIPT_PROMPT, + SCRIPT_DIALOG, DECIDE_POLICY, @@ -78,13 +77,20 @@ enum { PROP_ZOOM_LEVEL }; +typedef enum { + NotReplacingContent, + WillReplaceContent, + ReplacingContent, + DidReplaceContent +} ReplaceContentStatus; + struct _WebKitWebViewPrivate { WebKitWebContext* context; CString title; CString customTextEncoding; double estimatedLoadProgress; CString activeURI; - bool replacingContent; + ReplaceContentStatus replaceContentStatus; GRefPtr<WebKitBackForwardList> backForwardList; GRefPtr<WebKitSettings> settings; @@ -92,6 +98,8 @@ struct _WebKitWebViewPrivate { GRefPtr<WebKitHitTestResult> mouseTargetHitTestResult; unsigned mouseTargetModifiers; + + GRefPtr<WebKitFindController> findController; }; static guint signals[LAST_SIGNAL] = { 0, }; @@ -128,39 +136,56 @@ static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, Gt return dialog; } -static gboolean webkitWebViewScriptAlert(WebKitWebView* webView, const char* message) +static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDialog* scriptDialog) { - GtkWidget* dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE, message); - gtk_dialog_run(GTK_DIALOG(dialog)); + GtkWidget* dialog = 0; + + switch (scriptDialog->type) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE, scriptDialog->message.data()); + gtk_dialog_run(GTK_DIALOG(dialog)); + break; + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); + scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; + break; + case WEBKIT_SCRIPT_DIALOG_PROMPT: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); + GtkWidget* entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(entry), scriptDialog->defaultText.data()); + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry); + gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); + gtk_widget_show(entry); + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + scriptDialog->text = gtk_entry_get_text(GTK_ENTRY(entry)); + break; + } + gtk_widget_destroy(dialog); + return TRUE; } -static gboolean webkitWebViewScriptConfirm(WebKitWebView* webView, const char* message, gboolean* confirmed) +static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType) { - GtkWidget* dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, message); - *confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; - gtk_widget_destroy(dialog); + webkit_policy_decision_use(decision); return TRUE; } -static gboolean webkitWebViewScriptPrompt(WebKitWebView* webView, const char* message, const char* defaultText, char** text) +static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView) { - GtkWidget* dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, message); - GtkWidget* entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), defaultText); - gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry); - gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); - gtk_widget_show(entry); - - *text = (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) ? g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))) : 0; - return TRUE; + WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); + gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(settings); + gdouble pageZoomLevel = zoomTextOnly ? 1 : WKPageGetTextZoomFactor(wkPage); + gdouble textZoomLevel = zoomTextOnly ? WKPageGetPageZoomFactor(wkPage) : 1; + WKPageSetPageAndTextZoomFactors(wkPage, pageZoomLevel, textZoomLevel); } -static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType) +static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* settings, WKPageRef wkPage) { - webkit_policy_decision_use(decision); - return TRUE; + webView->priv->settings = settings; + webkitSettingsAttachSettingsToPage(webView->priv->settings.get(), wkPage); + g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView); } static void webkitWebViewConstructed(GObject* object) @@ -180,8 +205,9 @@ static void webkitWebViewConstructed(GObject* object) WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase); priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page)))); - priv->settings = adoptGRef(webkit_settings_new()); - webkitSettingsAttachSettingsToPage(priv->settings.get(), toAPI(page)); + + GRefPtr<WebKitSettings> settings = adoptGRef(webkit_settings_new()); + webkitWebViewSetSettings(webView, settings.get(), toAPI(page)); } static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) @@ -262,9 +288,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) webViewClass->load_failed = webkitWebViewLoadFail; webViewClass->create = webkitWebViewCreate; - webViewClass->script_alert = webkitWebViewScriptAlert; - webViewClass->script_confirm = webkitWebViewScriptConfirm; - webViewClass->script_prompt = webkitWebViewScriptPrompt; + webViewClass->script_dialog = webkitWebViewScriptDialog; webViewClass->decide_policy = webkitWebViewDecidePolicy; g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate)); @@ -494,75 +518,40 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_TYPE_NONE, 0); /** - * WebKitWebView::script-alert: - * @web_view: the #WebKitWebView on which the signal is emitted - * @message: the message text - * - * Emitted when JavaScript code calls <function>window.alert</function>. If the - * signal is not handled a message dialog with a single Close button will be - * shown with the message text. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. - */ - signals[SCRIPT_ALERT] = - g_signal_new("script-alert", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, script_alert), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, - G_TYPE_STRING); - - /** - * WebKitWebView::script-confirm: - * @web_view: the #WebKitWebView on which the signal is emitted - * @message: the message text - * @confirmed: (out): return location for confirm dialog response - * - * Emitted when JavaScript code calls <function>confirm</function>. If the - * signal is not handled a message dialog with OK and Cancel buttons will be - * shown with the message text. If OK button is clicked @confirmed will be - * set to %TRUE, otherwise it will be %FALSE. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. - */ - signals[SCRIPT_CONFIRM] = - g_signal_new("script-confirm", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__STRING_POINTER, - G_TYPE_BOOLEAN, 2, - G_TYPE_STRING, G_TYPE_POINTER); - - /** - * WebKitWebView::script-prompt: + * WebKitWebView::script-dialog: * @web_view: the #WebKitWebView on which the signal is emitted - * @message: the message text - * @default (allow-none): the default text - * @text: (out): return location for prompt dialog text response + * @dialog: the #WebKitScriptDialog to show * - * Emitted when JavaScript code calls <function>prompt</function>. If the - * signal is not handled a message dialog with OK and Cancel buttons and - * a text entry will be shown with the message text. If OK button is clicked - * @text will contain the text entered by the user, otherwise it will be %NULL. + * Emitted when JavaScript code calls <function>window.alert</function>, + * <function>window.confirm</function> or <function>window.prompt</function>. + * The @dialog parameter should be used to build the dialog. + * If the signal is not handled a different dialog will be built and shown depending + * on the dialog type: + * <itemizedlist> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_ALERT: message dialog with a single Close button. + * </para></listitem> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_CONFIRM: message dialog with OK and Cancel buttons. + * </para></listitem> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and + * a text entry with the default text. + * </para></listitem> + * </itemizedlist> * * Returns: %TRUE to stop other handlers from being invoked for the event. * %FALSE to propagate the event further. */ - signals[SCRIPT_PROMPT] = - g_signal_new("script-prompt", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, script_prompt), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__STRING_STRING_POINTER, - G_TYPE_BOOLEAN, 3, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + signals[SCRIPT_DIALOG] = + g_signal_new("script-dialog", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, script_dialog), + g_signal_accumulator_true_handled, 0, + webkit_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, 1, + WEBKIT_TYPE_SCRIPT_DIALOG | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitWebView::decide-policy: @@ -679,14 +668,30 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) WEBKIT_TYPE_PRINT_OPERATION); } -void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) +static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent loadEvent) { - if (webView->priv->replacingContent) { + if (webView->priv->replaceContentStatus == ReplacingContent) { if (loadEvent == WEBKIT_LOAD_FINISHED) - webView->priv->replacingContent = false; - return; + webView->priv->replaceContentStatus = DidReplaceContent; + return true; + } + + if (loadEvent == WEBKIT_LOAD_STARTED) { + if (webView->priv->replaceContentStatus == WillReplaceContent) { + webView->priv->replaceContentStatus = ReplacingContent; + return true; + } + webView->priv->replaceContentStatus = NotReplacingContent; } + return false; +} + +void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) +{ + if (updateReplaceContentStatus(webView, loadEvent)) + return; + if (loadEvent != WEBKIT_LOAD_FINISHED) webkitWebViewUpdateURI(webView); g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent); @@ -694,7 +699,7 @@ void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error) { - if (webView->priv->replacingContent) + if (webView->priv->replaceContentStatus == ReplacingContent) return; gboolean returnValue; @@ -714,7 +719,7 @@ void webkitWebViewSetTitle(WebKitWebView* webView, const CString& title) void webkitWebViewSetEstimatedLoadProgress(WebKitWebView* webView, double estimatedLoadProgress) { - if (webView->priv->replacingContent) + if (webView->priv->replaceContentStatus != NotReplacingContent) return; if (webView->priv->estimatedLoadProgress == estimatedLoadProgress) @@ -763,23 +768,25 @@ void webkitWebViewClosePage(WebKitWebView* webView) void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message) { + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_ALERT, message); gboolean returnValue; - g_signal_emit(webView, signals[SCRIPT_ALERT], 0, message.data(), &returnValue); + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); } bool webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message) { - gboolean returnValue, confirmed; - g_signal_emit(webView, signals[SCRIPT_CONFIRM], 0, message.data(), &confirmed, &returnValue); - return confirmed; + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_CONFIRM, message); + gboolean returnValue; + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); + return dialog.confirmed; } WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText) { + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText); gboolean returnValue; - GOwnPtr<char> text; - g_signal_emit(webView, signals[SCRIPT_PROMPT], 0, message.data(), defaultText.data(), &text.outPtr(), &returnValue); - return text ? WKStringCreateWithUTF8CString(text.get()) : 0; + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); + return dialog.text.isNull() ? 0 : WKStringCreateWithUTF8CString(dialog.text.data()); } void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision) @@ -965,7 +972,7 @@ void webkit_web_view_replace_content(WebKitWebView* webView, const gchar* conten g_return_if_fail(content); g_return_if_fail(contentURI); - webView->priv->replacingContent = true; + webView->priv->replaceContentStatus = WillReplaceContent; WKRetainPtr<WKStringRef> htmlString(AdoptWK, WKStringCreateWithUTF8CString(content)); WKRetainPtr<WKURLRef> contentURL(AdoptWK, WKURLCreateWithUTF8CString(contentURI)); @@ -1279,8 +1286,8 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settin if (webView->priv->settings == settings) return; - webView->priv->settings = settings; - webkitSettingsAttachSettingsToPage(settings, toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)))); + g_signal_handlers_disconnect_by_func(webView->priv->settings.get(), reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView); + webkitWebViewSetSettings(webView, settings, toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)))); } /** @@ -1338,11 +1345,14 @@ void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - if (WKPageGetPageZoomFactor(wkPage) == zoomLevel) + if (webkit_web_view_get_zoom_level(webView) == zoomLevel) return; - WKPageSetPageZoomFactor(wkPage, zoomLevel); + WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); + if (webkit_settings_get_zoom_text_only(webView->priv->settings.get())) + WKPageSetTextZoomFactor(wkPage, zoomLevel); + else + WKPageSetPageZoomFactor(wkPage, zoomLevel); g_object_notify(G_OBJECT(webView), "zoom-level"); } @@ -1360,10 +1370,10 @@ gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView) g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1); WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - return WKPageGetPageZoomFactor(wkPage); + gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get()); + return zoomTextOnly ? WKPageGetTextZoomFactor(wkPage) : WKPageGetPageZoomFactor(wkPage); } - static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t state, WKErrorRef, void* context) { GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context)); @@ -1436,3 +1446,23 @@ void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* WKRetainPtr<WKStringRef> wkCommand(AdoptWK, WKStringCreateWithUTF8CString(command)); WKPageExecuteCommand(toAPI(page), wkCommand.get()); } + +/** + * webkit_web_view_get_find_controller: + * @web_view: the #WebKitWebView + * + * Gets the #WebKitFindController that will allow the caller to query + * the #WebKitWebView for the text to look for. + * + * Returns: (transfer none): the #WebKitFindController associated to + * this particular #WebKitWebView. + */ +WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + + if (!webView->priv->findController) + webView->priv->findController = adoptGRef(WEBKIT_FIND_CONTROLLER(g_object_new(WEBKIT_TYPE_FIND_CONTROLLER, "web-view", webView, NULL))); + + return webView->priv->findController.get(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h index a1b21420b..fb4c48a2d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h @@ -30,7 +30,9 @@ #include <webkit2/WebKitBackForwardList.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitFindController.h> #include <webkit2/WebKitHitTestResult.h> +#include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitWebContext.h> @@ -47,7 +49,6 @@ G_BEGIN_DECLS #define WEBKIT_IS_WEB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_VIEW)) #define WEBKIT_WEB_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_VIEW, WebKitWebViewClass)) -typedef struct _WebKitWebView WebKitWebView; typedef struct _WebKitWebViewClass WebKitWebViewClass; typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate; @@ -77,7 +78,7 @@ typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate; * or to block the transfer of resources entirely. * * Enum values used for determining the type of a policy decision during - * WebKitWebView::decide-policy. + * #WebKitWebView::decide-policy. */ typedef enum { WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION, @@ -86,7 +87,7 @@ typedef enum { } WebKitPolicyDecisionType; /** - * WebKitLoadEvent + * WebKitLoadEvent: * @WEBKIT_LOAD_STARTED: A new load request has been made. * No data has been received yet, empty structures have * been allocated to perform the load; the load may still @@ -99,6 +100,9 @@ typedef enum { * load is being performed. * @WEBKIT_LOAD_FINISHED: Load completed. All resources are done loading * or there was an error during the load operation. + * + * Enum values used to denote the different events that happen during a + * #WebKitWebView load operation. */ typedef enum { WEBKIT_LOAD_STARTED, @@ -128,15 +132,9 @@ struct _WebKitWebViewClass { void (* ready_to_show) (WebKitWebView *web_view); void (* close) (WebKitWebView *web_view); - gboolean (* script_alert) (WebKitWebView *web_view, - const gchar *message); - gboolean (* script_confirm) (WebKitWebView *web_view, - const gchar *message, - gboolean *confirmed); - gboolean (* script_prompt) (WebKitWebView *web_view, - const gchar *message, - const gchar *default_text, - gchar **text); + gboolean (* script_dialog) (WebKitWebView *web_view, + WebKitScriptDialog *dialog); + gboolean (* decide_policy) (WebKitWebView *web_view, WebKitPolicyDecision *decision, WebKitPolicyDecisionType type); @@ -265,6 +263,10 @@ webkit_web_view_can_execute_editing_command_finish (WebKitWebView *w WEBKIT_API void webkit_web_view_execute_editing_command (WebKitWebView *web_view, const gchar *command); + +WEBKIT_API WebKitFindController * +webkit_web_view_get_find_controller (WebKitWebView *web_view); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml index 5cd859dad..4a9cc798c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml @@ -27,6 +27,7 @@ <xi:include href="xml/WebKitHitTestResult.xml"/> <xi:include href="xml/WebKitPrintOperation.xml"/> <xi:include href="xml/WebKitError.xml"/> + <xi:include href="xml/WebKitFindController.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 5bfc129b2..a8f54083a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt @@ -49,6 +49,8 @@ webkit_web_context_get_type WebKitWebView WebKitLoadEvent WebKitPolicyDecisionType +WebKitScriptDialog +WebKitScriptDialogType <SUBSECTION Editing Commands> WEBKIT_EDITING_COMMAND_CUT @@ -86,6 +88,12 @@ webkit_web_view_get_zoom_level webkit_web_view_can_execute_editing_command webkit_web_view_can_execute_editing_command_finish webkit_web_view_execute_editing_command +webkit_web_view_get_find_controller +webkit_script_dialog_get_dialog_type +webkit_script_dialog_get_message +webkit_script_dialog_confirm_set_confirmed +webkit_script_dialog_prompt_get_default_text +webkit_script_dialog_prompt_set_text <SUBSECTION Standard> WebKitWebViewClass @@ -95,9 +103,11 @@ WEBKIT_TYPE_WEB_VIEW WEBKIT_WEB_VIEW_CLASS WEBKIT_IS_WEB_VIEW_CLASS WEBKIT_WEB_VIEW_GET_CLASS +WEBKIT_TYPE_SCRIPT_DIALOG <SUBSECTION Private> webkit_web_view_get_type +webkit_script_dialog_get_type WebKitWebViewPrivate </SECTION> @@ -220,6 +230,8 @@ webkit_settings_get_enable_webaudio webkit_settings_set_enable_webaudio webkit_settings_get_enable_webgl webkit_settings_set_enable_webgl +webkit_settings_get_zoom_text_only +webkit_settings_set_zoom_text_only <SUBSECTION Standard> WebKitSettingsClass @@ -461,3 +473,30 @@ webkit_policy_error_quark webkit_download_error_quark </SECTION> +<SECTION> +<FILE>WebKitFindController</FILE> +WebKitFindController +WebKitFindOptions +webkit_find_controller_search +webkit_find_controller_search_finish +webkit_find_controller_search_next +webkit_find_controller_search_previous +webkit_find_controller_get_search_text +webkit_find_controller_count_matches +webkit_find_controller_get_options +webkit_find_controller_get_max_match_count +webkit_find_controller_get_web_view + +<SUBSECTION Standard> +WebKitFindControllerClass +WEBKIT_TYPE_FIND_CONTROLLER +WEBKIT_FIND_CONTROLLER +WEBKIT_IS_FIND_CONTROLLER +WEBKIT_FIND_CONTROLLER_CLASS +WEBKIT_IS_FIND_CONTROLLER_CLASS +WEBKIT_FIND_CONTROLLER_GET_CLASS + +<SUBSECTION Private> +WebKitFindControllerPrivate +webkit_find_controller_get_type +</SECTION> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types index cba2df42c..8e8d7b13a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types @@ -9,4 +9,5 @@ webkit_uri_response_get_type webkit_uri_request_get_type webkit_window_properties_get_type webkit_download_get_type - +webkit_find_controller_get_type +webkit_script_dialog_get_type diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am index 35ece6845..6adb2d5cd 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am +++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am @@ -1,15 +1,16 @@ if ENABLE_WEBKIT2 TEST_PROGS += \ - Programs/WebKit2APITests/TestWebKitWebContext \ - Programs/WebKit2APITests/TestWebKitWebView \ - Programs/WebKit2APITests/TestLoaderClient \ - Programs/WebKit2APITests/TestWebKitSettings \ Programs/WebKit2APITests/TestBackForwardList \ Programs/WebKit2APITests/TestDownloads \ + Programs/WebKit2APITests/TestLoaderClient \ + Programs/WebKit2APITests/TestPrinting \ + Programs/WebKit2APITests/TestWebKitFindController \ Programs/WebKit2APITests/TestWebKitPolicyClient \ - Programs/WebKit2APITests/TestWebViewEditor \ - Programs/WebKit2APITests/TestPrinting + Programs/WebKit2APITests/TestWebKitSettings \ + Programs/WebKit2APITests/TestWebKitWebContext \ + Programs/WebKit2APITests/TestWebKitWebView \ + Programs/WebKit2APITests/TestWebViewEditor noinst_PROGRAMS += $(TEST_PROGS) @@ -128,4 +129,10 @@ Programs_WebKit2APITests_TestPrinting_CPPFLAGS = $(webkit2_tests_cppflags) $(GTK Programs_WebKit2APITests_TestPrinting_LDADD = $(webkit2_tests_ldadd) $(GTK_UNIX_PRINTING_LIBS) Programs_WebKit2APITests_TestPrinting_LDFLAGS = $(webkit2_tests_ldflags) +Programs_WebKit2APITests_TestWebKitFindController_SOURCES = \ + Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp +Programs_WebKit2APITests_TestWebKitFindController_CPPFLAGS = $(webkit2_tests_cppflags) +Programs_WebKit2APITests_TestWebKitFindController_LDADD = $(webkit2_tests_ldadd) +Programs_WebKit2APITests_TestWebKitFindController_LDFLAGS = $(webkit2_tests_ldflags) + endif # ENABLE_WEBKIT2 diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp new file mode 100644 index 000000000..ae9ff2f7a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp @@ -0,0 +1,379 @@ +/* + * 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 "LoadTrackingTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> +#include <wtf/gobject/GRefPtr.h> + +static const char* testString = "<html><body>first testing second testing secondHalf</body></html>"; + +class FindControllerTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(FindControllerTest); + + FindControllerTest() + : m_findController(webkit_web_view_get_find_controller(m_webView)) + , m_runFindUntilCompletion(false) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_findController.get())); + } + + ~FindControllerTest() + { + if (m_findController) + g_signal_handlers_disconnect_matched(m_findController.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void find(const char* searchText, guint32 findOptions, guint maxMatchCount) + { + g_signal_connect(m_findController.get(), "found-text", G_CALLBACK(foundTextCallback), this); + g_signal_connect(m_findController.get(), "failed-to-find-text", G_CALLBACK(failedToFindTextCallback), this); + webkit_find_controller_search(m_findController.get(), searchText, findOptions, maxMatchCount); + } + + void count(const char* searchText, guint32 findOptions, guint maxMatchCount) + { + g_signal_connect(m_findController.get(), "counted-matches", G_CALLBACK(countedMatchesCallback), this); + webkit_find_controller_count_matches(m_findController.get(), searchText, findOptions, maxMatchCount); + } + + void waitUntilFindFinished() + { + m_runFindUntilCompletion = true; + g_main_loop_run(m_mainLoop); + } + + void waitUntilWebViewDrawSignal() + { + g_signal_connect_after(m_webView, "draw", G_CALLBACK(webViewDraw), this); + g_main_loop_run(m_mainLoop); + } + + GRefPtr<WebKitFindController> m_findController; + bool m_textFound; + unsigned m_matchCount; + +private: + bool m_runFindUntilCompletion; + + static void webViewDraw(GtkWidget *widget, cairo_t *cr, FindControllerTest* test) + { + g_main_loop_quit(test->m_mainLoop); + g_signal_handlers_disconnect_matched(widget, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, test); + } + + static void foundTextCallback(WebKitFindController*, guint matchCount, FindControllerTest* test) + { + test->m_textFound = true; + test->m_matchCount = matchCount; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } + + static void failedToFindTextCallback(WebKitFindController*, FindControllerTest* test) + { + test->m_textFound = false; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } + + static void countedMatchesCallback(WebKitFindController*, guint matchCount, FindControllerTest* test) + { + test->m_matchCount = matchCount; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } +}; + +static void testFindControllerTextFound(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); +} + +static void testFindControllerTextNotFound(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("notFound", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); +} + +static void testFindControllerMatchCount(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + g_assert(test->m_textFound); +} + +static void testFindControllerMaxMatchCount(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == G_MAXUINT); + g_assert(test->m_textFound); +} + +static void testFindControllerNext(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); +} + +static void testFindControllerPrevious(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); + + webkit_find_controller_search_previous(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS); +} + +static void testFindControllerCountedMatches(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->count("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + + test->count("first", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 1); + + test->count("notFound", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_matchCount); +} + +static void testFindControllerOptions(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("Testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Testing", WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("esting", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("esting", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Half", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Half", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS | WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("testing", WEBKIT_FIND_OPTIONS_WRAP_AROUND, 3); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); +} + +static gboolean gdkPixbufEqual(GdkPixbuf* firstPixbuf, GdkPixbuf* secondPixbuf) +{ + if (gdk_pixbuf_get_bits_per_sample(firstPixbuf) != gdk_pixbuf_get_bits_per_sample(secondPixbuf) + || gdk_pixbuf_get_has_alpha(firstPixbuf) != gdk_pixbuf_get_has_alpha(secondPixbuf) + || gdk_pixbuf_get_height(firstPixbuf) != gdk_pixbuf_get_height(secondPixbuf) + || gdk_pixbuf_get_n_channels(firstPixbuf) != gdk_pixbuf_get_n_channels(secondPixbuf) + || gdk_pixbuf_get_rowstride(firstPixbuf) != gdk_pixbuf_get_rowstride(secondPixbuf) + || gdk_pixbuf_get_width(firstPixbuf) != gdk_pixbuf_get_width(secondPixbuf)) + return FALSE; + + int pixbufRowstride = gdk_pixbuf_get_rowstride(firstPixbuf); + int pixbufHeight = gdk_pixbuf_get_height(firstPixbuf); + int pixbufWidth = gdk_pixbuf_get_width(firstPixbuf); + int numberOfChannels = gdk_pixbuf_get_n_channels(firstPixbuf); + int bitsPerSample = gdk_pixbuf_get_bits_per_sample(firstPixbuf); + + // Last row can be of different length. Taken from gdk-pixbuf documentation. + int totalLength = (pixbufHeight - 1) * pixbufRowstride \ + + pixbufWidth * ((numberOfChannels * bitsPerSample + 7) / 8); + + guchar* firstPixels = gdk_pixbuf_get_pixels(firstPixbuf); + guchar* secondPixels = gdk_pixbuf_get_pixels(secondPixbuf); + for (int i = 0; i < totalLength; i++) + if (firstPixels[i] != secondPixels[i]) + return FALSE; + + return TRUE; +} + +static void testFindControllerHide(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->showInWindowAndWaitUntilMapped(); + int allocatedHeight = gtk_widget_get_allocated_height(GTK_WIDGET(test->m_webView)); + int allocatedWidth = gtk_widget_get_allocated_width(GTK_WIDGET(test->m_webView)); + GdkWindow* webViewGdkWindow = gtk_widget_get_window(GTK_WIDGET(test->m_webView)); + g_assert(webViewGdkWindow); + + test->waitUntilWebViewDrawSignal(); + GRefPtr<GdkPixbuf> originalPixbuf = gdk_pixbuf_get_from_window(webViewGdkWindow, 0, 0, allocatedHeight, allocatedWidth); + g_assert(originalPixbuf); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + test->waitUntilWebViewDrawSignal(); + GRefPtr<GdkPixbuf> highlightPixbuf = gdk_pixbuf_get_from_window(webViewGdkWindow, 0, 0, allocatedHeight, allocatedWidth); + g_assert(highlightPixbuf); + g_assert(!gdkPixbufEqual(originalPixbuf.get(), highlightPixbuf.get())); + +#if (0) + // Requires http://webkit.org/b/77747 to be fixed + WebKitFindController* findController = webkit_web_view_get_find_controller(test->m_webView); + webkit_find_controller_search_finish(findController); + webkit_web_view_execute_editing_command(test->m_webView, "Unselect"); + + test->waitUntilWebViewDrawSignal(); + GRefPtr<GdkPixbuf> unhighlightPixbuf = gdk_pixbuf_get_from_window(webViewGdkWindow, 0, 0, allocatedHeight, allocatedWidth); + g_assert(unhighlightPixbuf); + g_assert(gdkPixbufEqual(originalPixbuf.get(), unhighlightPixbuf.get())); +#endif +} + +static void testFindControllerInstance(FindControllerTest* test, gconstpointer) +{ + WebKitFindController* findController1 = webkit_web_view_get_find_controller(test->m_webView); + WebKitFindController* findController2 = webkit_web_view_get_find_controller(test->m_webView); + + g_assert(findController1 == findController2); +} + +static void testFindControllerGetters(FindControllerTest* test, gconstpointer) +{ + const char* searchText = "testing"; + guint maxMatchCount = 1; + guint32 findOptions = WEBKIT_FIND_OPTIONS_WRAP_AROUND | WEBKIT_FIND_OPTIONS_AT_WORD_STARTS; + WebKitFindController* findController = webkit_web_view_get_find_controller(test->m_webView); + + webkit_find_controller_search(findController, searchText, findOptions, maxMatchCount); + g_assert(webkit_find_controller_get_web_view(findController) == test->m_webView); + g_assert(!g_strcmp0(webkit_find_controller_get_search_text(findController), searchText)); + g_assert(webkit_find_controller_get_max_match_count(findController) == maxMatchCount); + g_assert(webkit_find_controller_get_options(findController) == findOptions); +} + +void beforeAll() +{ + FindControllerTest::add("WebKitFindController", "getters", testFindControllerGetters); + FindControllerTest::add("WebKitFindController", "instance", testFindControllerInstance); + FindControllerTest::add("WebKitFindController", "text-found", testFindControllerTextFound); + FindControllerTest::add("WebKitFindController", "text-not-found", testFindControllerTextNotFound); + FindControllerTest::add("WebKitFindController", "match-count", testFindControllerMatchCount); + FindControllerTest::add("WebKitFindController", "max-match-count", testFindControllerMaxMatchCount); + FindControllerTest::add("WebKitFindController", "next", testFindControllerNext); + FindControllerTest::add("WebKitFindController", "previous", testFindControllerPrevious); + FindControllerTest::add("WebKitFindController", "counted-matches", testFindControllerCountedMatches); + FindControllerTest::add("WebKitFindController", "options", testFindControllerOptions); + FindControllerTest::add("WebKitFindController", "hide", testFindControllerHide); +} + +void afterAll() +{ +} diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp index a3ce7dece..03c5f2fe8 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp @@ -199,6 +199,11 @@ static void testWebKitSettings(Test*, gconstpointer) webkit_settings_set_enable_webgl(settings, TRUE); g_assert(webkit_settings_get_enable_webgl(settings)); + // Zoom text only is disabled by default. + g_assert(!webkit_settings_get_zoom_text_only(settings)); + webkit_settings_set_zoom_text_only(settings, TRUE); + g_assert(webkit_settings_get_zoom_text_only(settings)); + g_object_unref(G_OBJECT(settings)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp index 47da98eb3..bfeda169f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp @@ -71,24 +71,22 @@ static void testWebViewSettings(WebViewTest* test, gconstpointer) g_assert(webkit_settings_get_enable_javascript(settings)); } -static void replaceContentTitleChangedCallback(WebViewTest* test) +static void replaceContentLoadCallback(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) { - g_main_loop_quit(test->m_mainLoop); -} - -static void replaceContentLoadCallback() -{ - g_assert_not_reached(); + // There might be an event from a previous load, + // but never a WEBKIT_LOAD_STARTED after webkit_web_view_replace_content(). + g_assert_cmpint(loadEvent, !=, WEBKIT_LOAD_STARTED); } static void testWebViewReplaceContent(WebViewTest* test, gconstpointer) { - g_signal_connect_swapped(test->m_webView, "notify::title", G_CALLBACK(replaceContentTitleChangedCallback), test); + test->loadHtml("<html><head><title>Replace Content Test</title></head><body>Content to replace</body></html>", 0); + test->waitUntilTitleChangedTo("Replace Content Test"); + g_signal_connect(test->m_webView, "load-changed", G_CALLBACK(replaceContentLoadCallback), test); - g_signal_connect(test->m_webView, "load-failed", G_CALLBACK(replaceContentLoadCallback), test); - test->replaceContent("<html><head><title>Content Replaced</title></head><body>New Content</body></html>", + test->replaceContent("<html><body onload='document.title=\"Content Replaced\"'>New Content</body></html>", "http://foo.com/bar", 0); - g_main_loop_run(test->m_mainLoop); + test->waitUntilTitleChangedTo("Content Replaced"); } static const char* kAlertDialogMessage = "WebKitGTK+ alert dialog message"; @@ -106,12 +104,6 @@ public: Close }; - enum ScriptType { - Alert, - Confirm, - Prompt - }; - class WindowProperties { public: WindowProperties() @@ -226,43 +218,52 @@ public: return newWebView; } - static gboolean scriptAlert(WebKitWebView*, const char* message, UIClientTest* test) + void scriptAlert(WebKitScriptDialog* dialog) { - switch (test->m_scriptType) { - case UIClientTest::Alert: - g_assert_cmpstr(message, ==, kAlertDialogMessage); + switch (m_scriptDialogType) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kAlertDialogMessage); break; - case UIClientTest::Confirm: - g_assert(test->m_scriptDialogConfirmed); - g_assert_cmpstr(message, ==, "confirmed"); + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + g_assert(m_scriptDialogConfirmed); + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, "confirmed"); break; - case UIClientTest::Prompt: - g_assert_cmpstr(message, ==, kPromptDialogReturnedText); + case WEBKIT_SCRIPT_DIALOG_PROMPT: + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogReturnedText); break; } - g_main_loop_quit(test->m_mainLoop); - - return TRUE; + g_main_loop_quit(m_mainLoop); } - static gboolean scriptConfirm(WebKitWebView*, const char* message, gboolean* confirmed, UIClientTest* test) + void scriptConfirm(WebKitScriptDialog* dialog) { - g_assert_cmpstr(message, ==, kConfirmDialogMessage); - g_assert(confirmed); - test->m_scriptDialogConfirmed = !test->m_scriptDialogConfirmed; - *confirmed = test->m_scriptDialogConfirmed; + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kConfirmDialogMessage); + m_scriptDialogConfirmed = !m_scriptDialogConfirmed; + webkit_script_dialog_confirm_set_confirmed(dialog, m_scriptDialogConfirmed); + } - return TRUE; + void scriptPrompt(WebKitScriptDialog* dialog) + { + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogMessage); + g_assert_cmpstr(webkit_script_dialog_prompt_get_default_text(dialog), ==, "default"); + webkit_script_dialog_prompt_set_text(dialog, kPromptDialogReturnedText); } - static gboolean scriptPrompt(WebKitWebView*, const char* message, const char* defaultText, char **text, UIClientTest* test) + static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, UIClientTest* test) { - g_assert_cmpstr(message, ==, kPromptDialogMessage); - g_assert_cmpstr(defaultText, ==, "default"); - g_assert(text); - *text = g_strdup(kPromptDialogReturnedText); + switch (webkit_script_dialog_get_dialog_type(dialog)) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + test->scriptAlert(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + test->scriptConfirm(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_PROMPT: + test->scriptPrompt(dialog); + break; + } return TRUE; } @@ -278,15 +279,13 @@ public: } UIClientTest() - : m_scriptType(Alert) + : m_scriptDialogType(WEBKIT_SCRIPT_DIALOG_ALERT) , m_scriptDialogConfirmed(true) , 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-alert", G_CALLBACK(scriptAlert), this); - g_signal_connect(m_webView, "script-confirm", G_CALLBACK(scriptConfirm), this); - g_signal_connect(m_webView, "script-prompt", G_CALLBACK(scriptPrompt), this); + g_signal_connect(m_webView, "script-dialog", G_CALLBACK(scriptDialog), this); g_signal_connect(m_webView, "mouse-target-changed", G_CALLBACK(mouseTargetChanged), this); } @@ -313,7 +312,7 @@ public: } Vector<WebViewEvents> m_webViewEvents; - ScriptType m_scriptType; + WebKitScriptDialogType m_scriptDialogType; bool m_scriptDialogConfirmed; WindowProperties m_windowProperties; HashSet<WTF::String> m_windowPropertiesChanged; @@ -340,19 +339,19 @@ static void testWebViewJavaScriptDialogs(UIClientTest* test, gconstpointer) static const char* jsConfirmFormat = "do { confirmed = confirm('%s'); } while (!confirmed); alert('confirmed');"; static const char* jsPromptFormat = "alert(prompt('%s', 'default'));"; - test->m_scriptType = UIClientTest::Alert; + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_ALERT; GOwnPtr<char> alertDialogMessage(g_strdup_printf(jsAlertFormat, kAlertDialogMessage)); GOwnPtr<char> alertHTML(g_strdup_printf(htmlOnLoadFormat, alertDialogMessage.get())); test->loadHtml(alertHTML.get(), 0); test->waitUntilMainLoopFinishes(); - test->m_scriptType = UIClientTest::Confirm; + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_CONFIRM; GOwnPtr<char> confirmDialogMessage(g_strdup_printf(jsConfirmFormat, kConfirmDialogMessage)); GOwnPtr<char> confirmHTML(g_strdup_printf(htmlOnLoadFormat, confirmDialogMessage.get())); test->loadHtml(confirmHTML.get(), 0); test->waitUntilMainLoopFinishes(); - test->m_scriptType = UIClientTest::Prompt; + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_PROMPT; GOwnPtr<char> promptDialogMessage(g_strdup_printf(jsPromptFormat, kPromptDialogMessage)); GOwnPtr<char> promptHTML(g_strdup_printf(htmlOnLoadFormat, promptDialogMessage.get())); test->loadHtml(promptHTML.get(), 0); @@ -447,6 +446,10 @@ static void testWebViewZoomLevel(WebViewTest* test, gconstpointer) g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 1); webkit_web_view_set_zoom_level(test->m_webView, 2.5); g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5); + + webkit_settings_set_zoom_text_only(webkit_web_view_get_settings(test->m_webView), TRUE); + // The zoom level shouldn't change when zoom-text-only setting changes. + g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5); } void beforeAll() diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp index 00d3b3e20..31de72911 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp @@ -136,6 +136,28 @@ void WebViewTest::waitUntilLoadFinished() g_main_loop_run(m_mainLoop); } +static void titleChanged(WebKitWebView* webView, GParamSpec*, WebViewTest* test) +{ + if (!test->m_expectedTitle.isNull() && test->m_expectedTitle != webkit_web_view_get_title(webView)) + return; + + g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(titleChanged), test); + g_main_loop_quit(test->m_mainLoop); +} + +void WebViewTest::waitUntilTitleChangedTo(const char* expectedTitle) +{ + m_expectedTitle = expectedTitle; + g_signal_connect(m_webView, "notify::title", G_CALLBACK(titleChanged), this); + g_main_loop_run(m_mainLoop); + m_expectedTitle = CString(); +} + +void WebViewTest::waitUntilTitleChanged() +{ + waitUntilTitleChangedTo(0); +} + static gboolean parentWindowMapped(GtkWidget* widget, GdkEvent*, WebViewTest* test) { g_signal_handlers_disconnect_by_func(widget, reinterpret_cast<void*>(parentWindowMapped), test); diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h index 95a569cd6..01f468562 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h +++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h @@ -42,6 +42,8 @@ public: void wait(double seconds); void waitUntilLoadFinished(); + void waitUntilTitleChangedTo(const char* expectedTitle); + void waitUntilTitleChanged(); void showInWindowAndWaitUntilMapped(); void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0); @@ -50,6 +52,7 @@ public: GMainLoop* m_mainLoop; CString m_activeURI; GtkWidget* m_parentWindow; + CString m_expectedTitle; }; #endif // WebViewTest_h diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h index f78b873a3..0a807bc3d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h @@ -30,8 +30,10 @@ #include <webkit2/WebKitEditingCommands.h> #include <webkit2/WebKitEnumTypes.h> #include <webkit2/WebKitError.h> +#include <webkit2/WebKitFindController.h> #include <webkit2/WebKitHitTestResult.h> #include <webkit2/WebKitPrintOperation.h> +#include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitURIResponse.h> diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list index 77d269a75..5f7356039 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list @@ -1,15 +1,10 @@ +BOOLEAN:BOXED BOOLEAN:ENUM,STRING,POINTER BOOLEAN:OBJECT BOOLEAN:OBJECT,ENUM -BOOLEAN:OBJECT,STRING,POINTER -BOOLEAN:POINTER BOOLEAN:STRING -BOOLEAN:STRING,POINTER -BOOLEAN:STRING,STRING,POINTER -BOOLEAN:UINT64 -BOOLEAN:VOID OBJECT:VOID -VOID:ENUM VOID:OBJECT,UINT VOID:OBJECT,POINTER +VOID:UINT64 diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h index 953c378e1..dbe947a39 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h @@ -37,10 +37,6 @@ namespace WebKit { class FindIndicatorWindow; -// NOTE: This does not use String::operator NSString*() since that function -// expects to be called on the thread running WebCore. -NSString* nsStringFromWebCoreString(const String&); - class PageClientImpl : public PageClient { public: static PassOwnPtr<PageClientImpl> create(WKView*); @@ -59,7 +55,8 @@ private: virtual bool isViewFocused(); virtual bool isViewVisible(); virtual bool isViewInWindow(); - + virtual LayerHostingMode layerHostingMode(); + virtual void processDidCrash(); virtual void pageClosed(); virtual void didRelaunchProcess(); @@ -95,6 +92,7 @@ private: virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); virtual void accessibilityWebProcessTokenReceived(const CoreIPC::DataReference&); diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm index 35e0e2e70..71a1a5075 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm @@ -33,6 +33,7 @@ #import "WKAPICast.h" #import "WKStringCF.h" #import "WKViewInternal.h" +#import "StringUtilities.h" #import "WebContextMenuProxyMac.h" #import "WebEditCommandProxy.h" #import "WebPopupMenuProxyMac.h" @@ -51,6 +52,12 @@ - (NSCursor *)_cursorRectCursor; @end +#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) +@interface NSWindow (WebNSWindowDetails) +- (BOOL)_hostsLayersInWindowServer; +@end +#endif + using namespace WebCore; using namespace WebKit; @@ -104,11 +111,6 @@ using namespace WebKit; namespace WebKit { -NSString* nsStringFromWebCoreString(const String& string) -{ - return string.impl() ? HardAutorelease(WKStringCopyCFString(0, toAPI(string.impl()))) : @""; -} - PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView) { return adoptPtr(new PageClientImpl(wkView)); @@ -188,6 +190,18 @@ bool PageClientImpl::isViewInWindow() return [m_wkView window]; } +LayerHostingMode PageClientImpl::layerHostingMode() +{ +#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) + if (![m_wkView window]) + return LayerHostingModeDefault; + + return [[m_wkView window] _hostsLayersInWindowServer] ? LayerHostingModeInWindowServer : LayerHostingModeDefault; +#else + return LayerHostingModeDefault; +#endif +} + void PageClientImpl::processDidCrash() { [m_wkView _processDidCrash]; @@ -341,6 +355,11 @@ void PageClientImpl::exitAcceleratedCompositingMode() { [m_wkView _exitAcceleratedCompositingMode]; } + +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +{ + [m_wkView _updateAcceleratedCompositingMode:layerTreeContext]; +} #endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus) diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm index d50a7269a..a326dd089 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm @@ -40,6 +40,7 @@ #import "PDFViewController.h" #import "PageClientImpl.h" #import "PasteboardTypes.h" +#import "StringUtilities.h" #import "TextChecker.h" #import "TextCheckerState.h" #import "TiledCoreAnimationDrawingAreaProxy.h" @@ -373,6 +374,7 @@ struct WKViewInterpretKeyEventsParameters { // Send back an empty string to the plug-in. This will disable text input. _data->_page->sendComplexTextInputToPlugin(_data->_pluginComplexTextInputIdentifier, String()); + _data->_pluginComplexTextInputIdentifier = 0; // Always reset the identifier when the plugin is disabled. } typedef HashMap<SEL, String> SelectorNameMap; @@ -1262,8 +1264,10 @@ static const short kIOHIDEventTypeScroll = 6; if (string) { _data->_page->sendComplexTextInputToPlugin(_data->_pluginComplexTextInputIdentifier, string); - if (!usingLegacyCocoaTextInput) + if (!usingLegacyCocoaTextInput) { _data->_pluginComplexTextInputState = PluginComplexTextInputDisabled; + _data->_pluginComplexTextInputIdentifier = 0; // Always reset the identifier when the plugin is disabled. + } } return didHandleEvent; @@ -2458,6 +2462,12 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I _data->_layerHostingView = nullptr; } +- (void)_updateAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext +{ + [self _exitAcceleratedCompositingMode]; + [self _enterAcceleratedCompositingMode:layerTreeContext]; +} + - (void)_setAccessibilityWebProcessToken:(NSData *)data { _data->_remoteAccessibilityChild = WKAXRemoteElementForToken(data); diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h index fd3e152e9..83346d3f1 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h @@ -64,6 +64,7 @@ namespace WebKit { - (void)_enterAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext; - (void)_exitAcceleratedCompositingMode; +- (void)_updateAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext; - (void)_setAccessibilityWebProcessToken:(NSData *)data; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp index d164a6b85..9293c972f 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp @@ -24,8 +24,10 @@ #include "LayerTreeHostProxy.h" #include "QtWebPageEventHandler.h" #include "TransformationMatrix.h" +#include "WebLayerTreeRenderer.h" #include "qquickwebpage_p_p.h" #include "qquickwebview_p.h" +#include <QPolygonF> #include <QtQuick/QQuickCanvas> #include <QtQuick/QSGGeometryNode> #include <QtQuick/QSGMaterial> @@ -36,6 +38,7 @@ QQuickWebPage::QQuickWebPage(QQuickWebView* viewportItem) , d(new QQuickWebPagePrivate(this, viewportItem)) { setFlag(ItemHasContents); + setClip(true); // We do the transform from the top left so the viewport can assume the position 0, 0 // is always where rendering starts. @@ -63,18 +66,6 @@ void QQuickWebPagePrivate::initialize(WebKit::WebPageProxy* webPageProxy) eventHandler.reset(new QtWebPageEventHandler(toAPI(webPageProxy), q, viewportItem)); } -static float computeEffectiveOpacity(const QQuickItem* item) -{ - if (!item) - return 1; - - float opacity = item->opacity(); - if (opacity < 0.01) - return 0; - - return opacity * computeEffectiveOpacity(item->parentItem()); -} - void QQuickWebPagePrivate::setDrawingAreaSize(const QSize& size) { DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); @@ -89,69 +80,109 @@ void QQuickWebPagePrivate::paint(QPainter* painter) webPageProxy->drawingArea()->paintLayerTree(painter); } -void QQuickWebPagePrivate::paintToCurrentGLContext() -{ - if (!q->isVisible()) - return; - - QTransform transform = q->itemTransform(0, 0); - transform.scale(contentsScale, contentsScale); - - float opacity = computeEffectiveOpacity(q); - QRectF clipRect = viewportItem->mapRectToScene(viewportItem->boundingRect()); - - if (!clipRect.isValid()) - return; - - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (!drawingArea) - return; - - drawingArea->paintToCurrentGLContext(transform, opacity, clipRect); -} - struct PageProxyNode : public QSGRenderNode { - PageProxyNode(QQuickWebPagePrivate* page) - : m_pagePrivate(page) + PageProxyNode(PassRefPtr<WebLayerTreeRenderer> renderer) + : m_renderer(renderer) + , m_scale(1) { } virtual StateFlags changedStates() { - return StateFlags(DepthState) | StencilState | ScissorState | ColorState | BlendState - | CullState | ViewportState; + return StateFlags(StencilState) | ColorState | BlendState; } - virtual void render(const RenderState &) + virtual void render(const RenderState&) { - if (m_pagePrivate) - m_pagePrivate->paintToCurrentGLContext(); + QMatrix4x4 renderMatrix = matrix() ? *matrix() : QMatrix4x4(); + + // Have to apply render scale manualy because it is not applied on page item. + // http://trac.webkit.org/changeset/104450 + renderMatrix.scale(m_scale); + + // FIXME: Support non-rectangular clippings. + layerTreeRenderer()->paintToCurrentGLContext(renderMatrix, inheritedOpacity(), clipRect()); } ~PageProxyNode() { - if (m_pagePrivate) - m_pagePrivate->resetPaintNode(); + layerTreeRenderer()->purgeGLResources(); } - QQuickWebPagePrivate* m_pagePrivate; + WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); } + void setScale(float scale) { m_scale = scale; } + +private: + QRectF clipRect() const + { + // Start with an invalid rect. + QRectF resultRect(0, 0, -1, -1); + + for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) { + QMatrix4x4 clipMatrix; + if (clip->matrix()) + clipMatrix = *clip->matrix(); + QRectF currentClip; + + if (clip->isRectangular()) + currentClip = clipMatrix.mapRect(clip->clipRect()); + else { + const QSGGeometry* geometry = clip->geometry(); + // Assume here that clipNode has only coordinate data. + const QSGGeometry::Point2D* geometryPoints = geometry->vertexDataAsPoint2D(); + + // Clip region should be at least triangle to make valid clip. + if (geometry->vertexCount() < 3) + continue; + + QPolygonF polygon; + + for (int i = 0; i < geometry->vertexCount(); i++) + polygon.append(clipMatrix.map(QPoint(geometryPoints[i].x, geometryPoints[i].y))); + currentClip = polygon.boundingRect(); + } + + if (currentClip.isEmpty()) + continue; + + if (resultRect.isValid()) + resultRect &= currentClip; + else + resultRect = currentClip; + } + + return resultRect; + } + + RefPtr<WebLayerTreeRenderer> m_renderer; + float m_scale; }; QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { - if (!(flags() & ItemHasContents)) { - if (oldNode) - delete oldNode; - return 0; - } + if (!d->webPageProxy->drawingArea()) + return oldNode; + + LayerTreeHostProxy* layerTreeHostProxy = d->webPageProxy->drawingArea()->layerTreeHostProxy(); + WebLayerTreeRenderer* renderer = layerTreeHostProxy->layerTreeRenderer(); - PageProxyNode* proxyNode = static_cast<PageProxyNode*>(oldNode); - if (!proxyNode) { - proxyNode = new PageProxyNode(d); - d->m_paintNode = proxyNode; + PageProxyNode* node = static_cast<PageProxyNode*>(oldNode); + + if (node && node->layerTreeRenderer() != renderer) { + // This means that LayerTreeHostProxy was deleted and recreated while old paint node survived. + // This could happen if web process have crashed. In this case we have to recreate paint node. + delete node; + node = 0; } - return proxyNode; + renderer->syncRemoteContent(); + + if (!node) + node = new PageProxyNode(renderer); + + node->setScale(d->contentsScale); + + return node; } QtWebPageEventHandler* QQuickWebPage::eventHandler() const @@ -205,18 +236,8 @@ void QQuickWebPagePrivate::updateSize() viewportItem->updateContentsSize(scaledSize); } -void QQuickWebPagePrivate::resetPaintNode() -{ - m_paintNode = 0; - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (drawingArea && drawingArea->layerTreeHostProxy()) - drawingArea->layerTreeHostProxy()->purgeGLResources(); -} - QQuickWebPagePrivate::~QQuickWebPagePrivate() { - if (m_paintNode) - static_cast<PageProxyNode*>(m_paintNode)->m_pagePrivate = 0; } #include "moc_qquickwebpage_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h index dfd223dbe..b28174124 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h @@ -41,7 +41,7 @@ public: void updateSize(); - void paintToCurrentGLContext(); + void paintToCurrentGLContext(const QTransform&, float opacity, const QRectF& clipRect); void paint(QPainter*); void resetPaintNode(); diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index f40e28924..6e518ff12 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -23,7 +23,6 @@ #include "DownloadProxy.h" #include "DrawingAreaProxyImpl.h" -#include "QtDialogRunner.h" #include "QtDownloadManager.h" #include "QtWebContext.h" #include "QtWebIconDatabaseClient.h" @@ -38,6 +37,7 @@ #include "qquickwebpage_p_p.h" #include "qquickwebview_p_p.h" #include "qwebdownloaditem_p_p.h" +#include "qwebloadrequest_p.h" #include "qwebnavigationhistory_p.h" #include "qwebnavigationhistory_p_p.h" #include "qwebpreferences_p.h" @@ -79,9 +79,12 @@ QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport) , userDidOverrideContentHeight(false) , m_navigatorQtObjectEnabled(false) , m_renderToOffscreenBuffer(false) + , m_loadStartedSignalSent(false) + , m_dialogRunnerActive(false) { viewport->setFlags(QQuickItem::ItemClipsChildrenToShape); QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged())); + QObject::connect(viewport, SIGNAL(urlChanged()), viewport, SLOT(_q_onUrlChanged())); pageView.reset(new QQuickWebPage(viewport)); } @@ -112,7 +115,6 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl))); - QObject::connect(q_ptr, SIGNAL(urlChanged(QUrl)), iconDatabase, SLOT(requestIconForPageURL(QUrl))); // Any page setting should preferrable be set before creating the page. webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true); @@ -123,6 +125,16 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa webPageProxy->initializeWebPage(); } +void QQuickWebViewPrivate::setTransparentBackground(bool enable) +{ + webPageProxy->setDrawsTransparentBackground(enable); +} + +bool QQuickWebViewPrivate::transparentBackground() const +{ + return webPageProxy->drawsTransparentBackground(); +} + void QQuickWebViewPrivate::enableMouseEvents() { Q_Q(QQuickWebView); @@ -146,8 +158,17 @@ QPointF QQuickWebViewPrivate::pageItemPos() void QQuickWebViewPrivate::loadDidSucceed() { Q_Q(QQuickWebView); - emit q->navigationStateChanged(); - emit q->loadSucceeded(); + ASSERT(!q->loading()); + QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus); + emit q->loadingChanged(&loadRequest); +} + +void QQuickWebViewPrivate::onComponentComplete() +{ + if (m_deferedUrlToLoad.isEmpty()) + return; + + q_ptr->setUrl(m_deferedUrlToLoad); } void QQuickWebViewPrivate::setNeedsDisplay() @@ -173,6 +194,14 @@ void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const setIcon(iconURL); } +void QQuickWebViewPrivate::didChangeLoadingState(QWebLoadRequest* loadRequest) +{ + Q_Q(QQuickWebView); + ASSERT(q->loading() == (loadRequest->status() == QQuickWebView::LoadStartedStatus)); + emit q->loadingChanged(loadRequest); + m_loadStartedSignalSent = loadRequest->status() == QQuickWebView::LoadStartedStatus; +} + void QQuickWebViewPrivate::didChangeBackForwardList() { navigationHistory->d->reset(); @@ -180,15 +209,17 @@ void QQuickWebViewPrivate::didChangeBackForwardList() void QQuickWebViewPrivate::processDidCrash() { - emit q_ptr->navigationStateChanged(); pageView->eventHandler()->resetGestureRecognizers(); - WebCore::KURL url(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit()); - qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(QUrl(url).toString(QUrl::RemoveUserInfo))); + QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit())); + if (m_loadStartedSignalSent) { + QWebLoadRequest loadRequest(url, QQuickWebView::LoadFailedStatus, QLatin1String("The web process crashed."), QQuickWebView::InternalErrorDomain, 0); + didChangeLoadingState(&loadRequest); + } + qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(url.toString(QUrl::RemoveUserInfo))); } void QQuickWebViewPrivate::didRelaunchProcess() { - emit q_ptr->navigationStateChanged(); qWarning("WARNING: The web process has been successfully restarted."); pageView->d->setDrawingAreaSize(viewSize()); } @@ -217,6 +248,12 @@ void QQuickWebViewPrivate::_q_onVisibleChanged() webPageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible); } +void QQuickWebViewPrivate::_q_onUrlChanged() +{ + Q_Q(QQuickWebView); + context->iconDatabase()->requestIconForPageURL(q->url()); +} + void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem) { // Now that our downloadItem has everything we need we can emit downloadRequested. @@ -237,11 +274,8 @@ void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText) QtDialogRunner dialogRunner; if (!dialogRunner.initForAlert(alertDialog, q, alertText)) return; - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); } bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message) @@ -253,11 +287,8 @@ bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message) QtDialogRunner dialogRunner; if (!dialogRunner.initForConfirm(confirmDialog, q, message)) return true; - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); return dialogRunner.wasAccepted(); } @@ -275,11 +306,8 @@ QString QQuickWebViewPrivate::runJavaScriptPrompt(const QString& message, const ok = true; return defaultValue; } - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); ok = dialogRunner.wasAccepted(); return dialogRunner.result(); @@ -295,11 +323,7 @@ void QQuickWebViewPrivate::handleAuthenticationRequiredRequest(const QString& ho if (!dialogRunner.initForAuthentication(authenticationDialog, q, hostname, realm, prefilledUsername)) return; - setViewInAttachedProperties(dialogRunner.dialog()); - - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); username = dialogRunner.username(); password = dialogRunner.password(); @@ -315,10 +339,7 @@ void QQuickWebViewPrivate::handleProxyAuthenticationRequiredRequest(const QStrin if (!dialogRunner.initForProxyAuthentication(proxyAuthenticationDialog, q, hostname, port, prefilledUsername)) return; - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); username = dialogRunner.username(); password = dialogRunner.password(); @@ -334,13 +355,21 @@ bool QQuickWebViewPrivate::handleCertificateVerificationRequest(const QString& h if (!dialogRunner.initForCertificateVerification(certificateVerificationDialog, q, hostname)) return false; + execDialogRunner(dialogRunner); + + return dialogRunner.wasAccepted(); +} + +void QQuickWebViewPrivate::execDialogRunner(QtDialogRunner& dialogRunner) +{ setViewInAttachedProperties(dialogRunner.dialog()); disableMouseEvents(); + m_dialogRunnerActive = true; + dialogRunner.exec(); + m_dialogRunnerActive = false; enableMouseEvents(); - - return dialogRunner.wasAccepted(); } void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type) @@ -417,7 +446,7 @@ void QQuickWebViewPrivate::setIcon(const QUrl& iconURL) } m_iconURL = iconURL; - emit q->iconChanged(m_iconURL); + emit q->iconChanged(); } bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const @@ -433,6 +462,14 @@ void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled) context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled); } +QRect QQuickWebViewPrivate::visibleContentsRect() const +{ + Q_Q(const QQuickWebView); + const QRectF visibleRect(q->boundingRect().intersected(pageView->boundingRect())); + + return q->mapRectToWebContent(visibleRect).toAlignedRect(); +} + WebCore::IntSize QQuickWebViewPrivate::viewSize() const { return WebCore::IntSize(pageView->width(), pageView->height()); @@ -547,6 +584,8 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() // Trigger setting of correct visibility flags after everything was allocated and initialized. _q_onVisibleChanged(); + + QQuickWebViewPrivate::onComponentComplete(); } void QQuickWebViewFlickablePrivate::loadDidSucceed() @@ -609,16 +648,14 @@ void QQuickWebViewFlickablePrivate::_q_commitScaleChange() return; Q_Q(QQuickWebView); - const QRectF visibleRectInCSSCoordinates = q->mapRectToWebContent(q->boundingRect()).intersected(pageView->boundingRect()); - float scale = pageView->contentsScale(); - // This is only for our QML ViewportInfo debugging API. q->experimental()->viewportInfo()->didUpdateCurrentScale(); - QRect alignedVisibleContentRect = visibleRectInCSSCoordinates.toAlignedRect(); - drawingArea->setVisibleContentsRectForScaling(alignedVisibleContentRect, scale); + const QRect visibleRect(visibleContentsRect()); + float scale = pageView->contentsScale(); - webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect); + drawingArea->setVisibleContentsRectForScaling(visibleRect, scale); + webPageProxy->setFixedVisibleContentRect(visibleRect); } void QQuickWebViewPrivate::_q_commitPositionChange(const QPointF& trajectoryVector) @@ -627,21 +664,19 @@ void QQuickWebViewPrivate::_q_commitPositionChange(const QPointF& trajectoryVect if (!drawingArea) return; - Q_Q(QQuickWebView); - const QRectF visibleRectInCSSCoordinates = q->mapRectToWebContent(q->boundingRect()).intersected(pageView->boundingRect()); - - QRect alignedVisibleContentRect = visibleRectInCSSCoordinates.toAlignedRect(); - drawingArea->setVisibleContentsRectForPanning(alignedVisibleContentRect, trajectoryVector); + const QRect visibleRect(visibleContentsRect()); + drawingArea->setVisibleContentsRectForPanning(visibleRect, trajectoryVector); if (!trajectoryVector.isNull()) return; - webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect); + webPageProxy->setFixedVisibleContentRect(visibleRect); } void QQuickWebViewFlickablePrivate::_q_suspend() { pageIsSuspended = true; + webPageProxy->suspendActiveDOMObjectsAndAnimations(); } void QQuickWebViewFlickablePrivate::_q_resume() @@ -650,6 +685,7 @@ void QQuickWebViewFlickablePrivate::_q_resume() return; pageIsSuspended = false; + webPageProxy->resumeActiveDOMObjectsAndAnimations(); if (isTransitioningToNewPage) { isTransitioningToNewPage = false; @@ -786,6 +822,17 @@ bool QQuickWebViewExperimental::renderToOffscreenBuffer() const return d->renderToOffscreenBuffer(); } +bool QQuickWebViewExperimental::transparentBackground() const +{ + Q_D(const QQuickWebView); + return d->transparentBackground(); +} +void QQuickWebViewExperimental::setTransparentBackground(bool enable) +{ + Q_D(QQuickWebView); + d->setTransparentBackground(enable); +} + void QQuickWebViewExperimental::setFlickableViewportEnabled(bool enable) { s_flickableViewportEnabled = enable; @@ -1093,6 +1140,7 @@ QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRe { Q_D(QQuickWebView); d->initialize(contextRef, pageGroupRef); + setClip(true); } QQuickWebView::~QQuickWebView() @@ -1105,15 +1153,6 @@ QQuickWebPage* QQuickWebView::page() return d->pageView.data(); } -void QQuickWebView::load(const QUrl& url) -{ - if (url.isEmpty()) - return; - - Q_D(QQuickWebView); - d->webPageProxy->loadURL(url.toString()); -} - void QQuickWebView::goBack() { Q_D(QQuickWebView); @@ -1148,6 +1187,21 @@ QUrl QQuickWebView::url() const return QUrl(QString(mainFrame->url())); } +void QQuickWebView::setUrl(const QUrl& url) +{ + Q_D(QQuickWebView); + + if (url.isEmpty()) + return; + + if (!isComponentComplete()) { + d->m_deferedUrlToLoad = url; + return; + } + + d->webPageProxy->loadURL(url.toString()); +} + QUrl QQuickWebView::icon() const { Q_D(const QQuickWebView); @@ -1179,15 +1233,6 @@ bool QQuickWebView::loading() const return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState()); } -bool QQuickWebView::canReload() const -{ - Q_D(const QQuickWebView); - RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame(); - if (mainFrame) - return (WebFrameProxy::LoadStateFinished == mainFrame->loadState()); - return d->webPageProxy->backForwardList()->currentItem(); -} - QPointF QQuickWebView::mapToWebContent(const QPointF& pointInViewCoordinates) const { Q_D(const QQuickWebView); @@ -1281,128 +1326,125 @@ void QQuickWebView::componentComplete() void QQuickWebView::keyPressEvent(QKeyEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleKeyPressEvent(event); } void QQuickWebView::keyReleaseEvent(QKeyEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleKeyReleaseEvent(event); } void QQuickWebView::inputMethodEvent(QInputMethodEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleInputMethodEvent(event); } void QQuickWebView::focusInEvent(QFocusEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleFocusInEvent(event); } void QQuickWebView::focusOutEvent(QFocusEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleFocusOutEvent(event); } void QQuickWebView::touchEvent(QTouchEvent* event) { + Q_D(QQuickWebView); + if (d->m_dialogRunnerActive) { + event->ignore(); + return; + } + forceActiveFocus(); - this->event(event); + d->pageView->eventHandler()->handleTouchEvent(event); } void QQuickWebView::mousePressEvent(QMouseEvent* event) { + Q_D(QQuickWebView); forceActiveFocus(); - this->event(event); + d->pageView->eventHandler()->handleMousePressEvent(event); } void QQuickWebView::mouseMoveEvent(QMouseEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleMouseMoveEvent(event); } void QQuickWebView::mouseReleaseEvent(QMouseEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleMouseReleaseEvent(event); } void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event) { - this->event(event); + Q_D(QQuickWebView); + // If a MouseButtonDblClick was received then we got a MouseButtonPress before + // handleMousePressEvent will take care of double clicks. + d->pageView->eventHandler()->handleMousePressEvent(event); } void QQuickWebView::wheelEvent(QWheelEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleWheelEvent(event); } void QQuickWebView::hoverEnterEvent(QHoverEvent* event) { - this->event(event); + Q_D(QQuickWebView); + // Map HoverEnter to Move, for WebKit the distinction doesn't matter. + d->pageView->eventHandler()->handleHoverMoveEvent(event); } void QQuickWebView::hoverMoveEvent(QHoverEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleHoverMoveEvent(event); } void QQuickWebView::hoverLeaveEvent(QHoverEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleHoverLeaveEvent(event); } void QQuickWebView::dragMoveEvent(QDragMoveEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDragMoveEvent(event); } void QQuickWebView::dragEnterEvent(QDragEnterEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDragEnterEvent(event); } void QQuickWebView::dragLeaveEvent(QDragLeaveEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDragLeaveEvent(event); } void QQuickWebView::dropEvent(QDropEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDropEvent(event); } bool QQuickWebView::event(QEvent* ev) { - Q_D(QQuickWebView); - - switch (ev->type()) { - case QEvent::MouseMove: - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::Wheel: - case QEvent::HoverLeave: - case QEvent::HoverEnter: - case QEvent::HoverMove: - case QEvent::DragEnter: - case QEvent::DragLeave: - case QEvent::DragMove: - case QEvent::Drop: - case QEvent::KeyPress: - case QEvent::KeyRelease: - case QEvent::FocusIn: - case QEvent::FocusOut: - case QEvent::TouchBegin: - case QEvent::TouchEnd: - case QEvent::TouchCancel: - case QEvent::TouchUpdate: - if (d->pageView->eventHandler()->handleEvent(ev)) - return true; - } - - if (ev->type() == QEvent::InputMethod) - return false; // This is necessary to avoid an endless loop in connection with QQuickItem::event(). - + // Re-implemented for possible future use without breaking binary compatibility. return QQuickItem::event(ev); } diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index 674c18fe7..5302916eb 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -30,6 +30,7 @@ class QWebNavigationRequest; class QDeclarativeComponent; class QQuickWebPage; class QQuickWebViewAttached; +class QWebLoadRequest; class QQuickWebViewPrivate; class QQuickWebViewExperimental; class QWebDownloadItem; @@ -67,24 +68,30 @@ QT_END_NAMESPACE class QWEBKIT_EXPORT QQuickWebView : public QQuickItem { Q_OBJECT Q_PROPERTY(QString title READ title NOTIFY titleChanged) - Q_PROPERTY(QUrl url READ url NOTIFY urlChanged) + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged FINAL) + Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationHistoryChanged FINAL) + Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationHistoryChanged FINAL) + Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged FINAL) Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged) - Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationStateChanged FINAL) - Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationStateChanged FINAL) - Q_PROPERTY(bool loading READ loading NOTIFY navigationStateChanged FINAL) - Q_PROPERTY(bool canReload READ canReload NOTIFY navigationStateChanged FINAL) Q_ENUMS(NavigationRequestAction) + Q_ENUMS(LoadStatus) Q_ENUMS(ErrorDomain) Q_ENUMS(NavigationType) public: enum NavigationRequestAction { AcceptRequest, - IgnoreRequest + // Make room in the valid range of the enum for extra actions exposed in Experimental. + IgnoreRequest = 0xFF + }; + enum LoadStatus { + LoadStartedStatus, + LoadSucceededStatus, + LoadFailedStatus }; - enum ErrorDomain { + NoErrorDomain, InternalErrorDomain, NetworkErrorDomain, HttpErrorDomain, @@ -104,6 +111,7 @@ public: virtual ~QQuickWebView(); QUrl url() const; + void setUrl(const QUrl&); QUrl icon() const; QString title() const; int loadProgress() const; @@ -111,7 +119,6 @@ public: bool canGoBack() const; bool canGoForward() const; bool loading() const; - bool canReload() const; virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const; @@ -132,7 +139,6 @@ public: QPointF pageItemPos(); public Q_SLOTS: - void load(const QUrl&); void loadHtml(const QString& html, const QUrl& baseUrl = QUrl()); void goBack(); @@ -141,15 +147,13 @@ public Q_SLOTS: void reload(); Q_SIGNALS: - void titleChanged(const QString& title); - void loadStarted(); - void loadSucceeded(); - void loadFailed(QQuickWebView::ErrorDomain errorDomain, int errorCode, const QUrl& url, const QString& description); - void loadProgressChanged(int progress); - void urlChanged(const QUrl& url); - void iconChanged(const QUrl& iconURL); - void linkHovered(const QUrl& url, const QString& title); - void navigationStateChanged(); + void titleChanged(); + void navigationHistoryChanged(); + void loadingChanged(QWebLoadRequest* loadRequest); + void loadProgressChanged(); + void urlChanged(); + void iconChanged(); + void linkHovered(const QUrl& hoveredUrl, const QString& hoveredTitle); void navigationRequested(QWebNavigationRequest* request); protected: @@ -189,6 +193,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFilesSelected()); Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFinished(int result)); Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged()); + Q_PRIVATE_SLOT(d_func(), void _q_onUrlChanged()); Q_PRIVATE_SLOT(d_func(), void _q_onReceivedResponseFromDownload(QWebDownloadItem*)); Q_PRIVATE_SLOT(d_func(), void _q_onIconChangedForPageURL(const QUrl&, const QUrl&)); // Hides QObject::d_ptr allowing us to use the convenience macros. @@ -233,6 +238,7 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged) Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT) Q_PROPERTY(QDeclarativeListProperty<QObject> flickableData READ flickableData) + Q_PROPERTY(bool transparentBackground WRITE setTransparentBackground READ transparentBackground) Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL) Q_PROPERTY(QDeclarativeComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged) @@ -245,11 +251,11 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL) Q_PROPERTY(QWebViewportInfo* viewportInfo READ viewportInfo CONSTANT FINAL) Q_PROPERTY(QDeclarativeListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates) - Q_ENUMS(NavigationRequestAction) + Q_ENUMS(NavigationRequestActionExperimental) public: - enum NavigationRequestAction { - DownloadRequest = 2 + enum NavigationRequestActionExperimental { + DownloadRequest = QQuickWebView::IgnoreRequest - 1 }; QQuickWebViewExperimental(QQuickWebView* webView); @@ -294,6 +300,8 @@ public: void setContentX(qreal); qreal contentY() const; void setContentY(qreal); + bool transparentBackground() const; + void setTransparentBackground(bool); // C++ only bool renderToOffscreenBuffer() const; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index 300b4759d..39a14a7a6 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -22,6 +22,7 @@ #define qquickwebview_p_p_h #include "DrawingAreaProxy.h" +#include "QtDialogRunner.h" #include "QtFlickProvider.h" #include "QtPageClient.h" #include "QtViewportInteractionEngine.h" @@ -73,10 +74,11 @@ public: virtual void updateContentsSize(const QSizeF&) { } virtual void loadDidSucceed(); - virtual void onComponentComplete() { } + virtual void onComponentComplete(); virtual void loadDidCommit() { } virtual void didFinishFirstNonEmptyLayout() { } virtual void didChangeViewportProperties(const WebCore::ViewportArguments& args) { } + void didChangeLoadingState(QWebLoadRequest* loadRequest); void didChangeBackForwardList(); void setNeedsDisplay(); @@ -94,6 +96,7 @@ public: void _q_onOpenPanelFilesSelected(); void _q_onOpenPanelFinished(int result); void _q_onVisibleChanged(); + void _q_onUrlChanged(); void _q_onReceivedResponseFromDownload(QWebDownloadItem*); void _q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURLString); @@ -106,14 +109,20 @@ public: bool handleCertificateVerificationRequest(const QString& hostname); void handleProxyAuthenticationRequiredRequest(const QString& hostname, uint16_t port, const QString& prefilledUsername, QString& username, QString& password); + void execDialogRunner(QtDialogRunner&); + void setRenderToOffscreenBuffer(bool enable) { m_renderToOffscreenBuffer = enable; } + void setTransparentBackground(bool); void setViewInAttachedProperties(QObject*); void setIcon(const QUrl&); bool navigatorQtObjectEnabled() const; bool renderToOffscreenBuffer() const { return m_renderToOffscreenBuffer; } + bool transparentBackground() const; void setNavigatorQtObjectEnabled(bool); + QRect visibleContentsRect() const; + // PageClient. WebCore::IntSize viewSize() const; void didReceiveMessageFromNavigatorQtObject(const String& message); @@ -158,7 +167,10 @@ protected: bool userDidOverrideContentHeight; bool m_navigatorQtObjectEnabled; bool m_renderToOffscreenBuffer; + bool m_loadStartedSignalSent; + bool m_dialogRunnerActive; QUrl m_iconURL; + QUrl m_deferedUrlToLoad; }; class QQuickWebViewLegacyPrivate : public QQuickWebViewPrivate { diff --git a/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp new file mode 100644 index 000000000..0b249a61a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp @@ -0,0 +1,75 @@ +/* + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + + 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 "qwebloadrequest_p.h" + +class QWebLoadRequestPrivate { +public: + QWebLoadRequestPrivate(const QUrl& url, QQuickWebView::LoadStatus status, const QString& errorString, QQuickWebView::ErrorDomain errorDomain, int errorCode) + : url(url) + , status(status) + , errorString(errorString) + , errorDomain(errorDomain) + , errorCode(errorCode) + { + } + + QUrl url; + QQuickWebView::LoadStatus status; + QString errorString; + QQuickWebView::ErrorDomain errorDomain; + int errorCode; +}; + +QWebLoadRequest::QWebLoadRequest(const QUrl& url, QQuickWebView::LoadStatus status, const QString& errorString, QQuickWebView::ErrorDomain errorDomain, int errorCode, QObject* parent) + : QObject(parent) + , d(new QWebLoadRequestPrivate(url, status, errorString, errorDomain, errorCode)) +{ +} + +QWebLoadRequest::~QWebLoadRequest() +{ +} + +QUrl QWebLoadRequest::url() const +{ + return d->url; +} + +QQuickWebView::LoadStatus QWebLoadRequest::status() const +{ + return d->status; +} + +QString QWebLoadRequest::errorString() const +{ + return d->errorString; +} + +QQuickWebView::ErrorDomain QWebLoadRequest::errorDomain() const +{ + return d->errorDomain; +} + +int QWebLoadRequest::errorCode() const +{ + return d->errorCode; +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebloadrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest_p.h new file mode 100644 index 000000000..ebff399a7 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest_p.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + + 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 qwebloadrequest_p_h +#define qwebloadrequest_p_h + +#include "qquickwebview_p.h" +#include <QtCore/QObject> +#include <QtCore/QScopedPointer> +#include <QtCore/QUrl> + +class QWebLoadRequestPrivate; + +class QWEBKIT_EXPORT QWebLoadRequest : public QObject { + Q_OBJECT + Q_PROPERTY(QUrl url READ url) + Q_PROPERTY(QQuickWebView::LoadStatus status READ status) + Q_PROPERTY(QString errorString READ errorString) + Q_PROPERTY(QQuickWebView::ErrorDomain errorDomain READ errorDomain) + Q_PROPERTY(int errorCode READ errorCode) + +public: + QWebLoadRequest(const QUrl& url, QQuickWebView::LoadStatus status, const QString& errorString = QString(), QQuickWebView::ErrorDomain errorDomain = QQuickWebView::NoErrorDomain, int errorCode = 0, QObject* parent = 0); + ~QWebLoadRequest(); + QUrl url() const; + QQuickWebView::LoadStatus status() const; + QString errorString() const; + QQuickWebView::ErrorDomain errorDomain() const; + int errorCode() const; + +private: + QScopedPointer<QWebLoadRequestPrivate> d; +}; + +#endif // qwebloadrequest_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp index 3a63f80e3..92af27179 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp @@ -25,12 +25,10 @@ class QWebNavigationRequestPrivate { public: - QWebNavigationRequestPrivate(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, - Qt::KeyboardModifiers modifiers, QQuickWebView::NavigationType navigationType) + QWebNavigationRequestPrivate(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType) : url(url) - , originatingUrl(originatingUrl) - , button(button) - , modifiers(modifiers) + , mouseButton(mouseButton) + , keyboardModifiers(keyboardModifiers) , action(QQuickWebView::AcceptRequest) , navigationType(navigationType) { @@ -41,17 +39,15 @@ public: } QUrl url; - QUrl originatingUrl; - Qt::MouseButton button; - Qt::KeyboardModifiers modifiers; - int action; + Qt::MouseButton mouseButton; + Qt::KeyboardModifiers keyboardModifiers; + QQuickWebView::NavigationRequestAction action; QQuickWebView::NavigationType navigationType; }; -QWebNavigationRequest::QWebNavigationRequest(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, - Qt::KeyboardModifiers modifiers, QQuickWebView::NavigationType navigationType, QObject* parent) +QWebNavigationRequest::QWebNavigationRequest(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, QObject* parent) : QObject(parent) - , d(new QWebNavigationRequestPrivate(url, originatingUrl, button, modifiers, navigationType)) + , d(new QWebNavigationRequestPrivate(url, mouseButton, keyboardModifiers, navigationType)) { } @@ -60,7 +56,7 @@ QWebNavigationRequest::~QWebNavigationRequest() delete d; } -void QWebNavigationRequest::setAction(int action) +void QWebNavigationRequest::setAction(QQuickWebView::NavigationRequestAction action) { if (d->action == action) return; @@ -74,24 +70,19 @@ QUrl QWebNavigationRequest::url() const return d->url; } -QUrl QWebNavigationRequest::originatingUrl() const +int QWebNavigationRequest::mouseButton() const { - return d->originatingUrl; + return int(d->mouseButton); } -int QWebNavigationRequest::button() const +int QWebNavigationRequest::keyboardModifiers() const { - return int(d->button); + return int(d->keyboardModifiers); } -int QWebNavigationRequest::modifiers() const +QQuickWebView::NavigationRequestAction QWebNavigationRequest::action() const { - return int(d->modifiers); -} - -int QWebNavigationRequest::action() const -{ - return int(d->action); + return d->action; } QQuickWebView::NavigationType QWebNavigationRequest::navigationType() const diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h index 46333f0e8..b401deda5 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h @@ -31,24 +31,21 @@ class QWebNavigationRequestPrivate; class QWEBKIT_EXPORT QWebNavigationRequest : public QObject { Q_OBJECT Q_PROPERTY(QUrl url READ url CONSTANT FINAL) - Q_PROPERTY(QUrl originatingUrl READ originatingUrl CONSTANT FINAL) - Q_PROPERTY(int button READ button CONSTANT FINAL) - Q_PROPERTY(int modifiers READ modifiers CONSTANT FINAL) - Q_PROPERTY(int action READ action WRITE setAction NOTIFY actionChanged FINAL) + Q_PROPERTY(int mouseButton READ mouseButton CONSTANT FINAL) + Q_PROPERTY(int keyboardModifiers READ keyboardModifiers CONSTANT FINAL) + Q_PROPERTY(QQuickWebView::NavigationRequestAction action READ action WRITE setAction NOTIFY actionChanged FINAL) Q_PROPERTY(QQuickWebView::NavigationType navigationType READ navigationType CONSTANT FINAL) public: - QWebNavigationRequest(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, - QQuickWebView::NavigationType navigationType, QObject* parent = 0); + QWebNavigationRequest(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, QObject* parent = 0); ~QWebNavigationRequest(); QUrl url() const; - QUrl originatingUrl() const; - int button() const; - int modifiers() const; - int action() const; + int mouseButton() const; + int keyboardModifiers() const; + QQuickWebView::NavigationRequestAction action() const; - void setAction(int action); + void setAction(QQuickWebView::NavigationRequestAction action); QQuickWebView::NavigationType navigationType() const; Q_SIGNALS: diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h index 653018221..ab422e4e7 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h @@ -18,7 +18,7 @@ * */ -#ifndef qwebviewportinfp_p_h +#ifndef qwebviewportinfo_p_h #define qwebviewportinfo_p_h #include "qwebkitglobal.h" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro index 0f0d4f52c..02dc197c7 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro @@ -1,3 +1,3 @@ include(../tests.pri) SOURCES += $${TARGET}.cpp -CONFIG += qtwebkit-private +QT += webkit-private diff --git a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp index 3ad4729a9..f5f976663 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp @@ -23,8 +23,9 @@ #include <QMetaProperty> #include <QMetaType> #include <QtTest/QtTest> -#include <qquickwebview_p.h> -#include <qwebnavigationrequest_p.h> +#include <private/qquickwebview_p.h> +#include <private/qwebloadrequest_p.h> +#include <private/qwebnavigationrequest_p.h> class tst_publicapi : public QObject { Q_OBJECT @@ -34,11 +35,16 @@ private slots: static QList<const QMetaObject*> typesToCheck = QList<const QMetaObject*>() << &QQuickWebView::staticMetaObject + << &QWebLoadRequest::staticMetaObject << &QWebNavigationRequest::staticMetaObject; static QStringList expectedAPI = QStringList() << "QQuickWebView.AcceptRequest --> NavigationRequestAction" << "QQuickWebView.IgnoreRequest --> NavigationRequestAction" + << "QQuickWebView.LoadStartedStatus --> LoadStatus" + << "QQuickWebView.LoadSucceededStatus --> LoadStatus" + << "QQuickWebView.LoadFailedStatus --> LoadStatus" + << "QQuickWebView.NoErrorDomain --> ErrorDomain" << "QQuickWebView.InternalErrorDomain --> ErrorDomain" << "QQuickWebView.NetworkErrorDomain --> ErrorDomain" << "QQuickWebView.HttpErrorDomain --> ErrorDomain" @@ -52,33 +58,33 @@ static QStringList expectedAPI = QStringList() << "QQuickWebView.title --> QString" << "QQuickWebView.url --> QUrl" << "QQuickWebView.icon --> QUrl" - << "QQuickWebView.loadProgress --> int" << "QQuickWebView.canGoBack --> bool" << "QQuickWebView.canGoForward --> bool" << "QQuickWebView.loading --> bool" - << "QQuickWebView.canReload --> bool" - << "QQuickWebView.titleChanged(QString) --> void" - << "QQuickWebView.loadStarted() --> void" - << "QQuickWebView.loadSucceeded() --> void" - << "QQuickWebView.loadFailed(QQuickWebView::ErrorDomain,int,QUrl,QString) --> void" - << "QQuickWebView.loadProgressChanged(int) --> void" - << "QQuickWebView.urlChanged(QUrl) --> void" - << "QQuickWebView.iconChanged(QUrl) --> void" + << "QQuickWebView.loadProgress --> int" + << "QQuickWebView.titleChanged() --> void" + << "QQuickWebView.navigationHistoryChanged() --> void" + << "QQuickWebView.loadingChanged(QWebLoadRequest*) --> void" + << "QQuickWebView.loadProgressChanged() --> void" + << "QQuickWebView.urlChanged() --> void" + << "QQuickWebView.iconChanged() --> void" << "QQuickWebView.linkHovered(QUrl,QString) --> void" - << "QQuickWebView.navigationStateChanged() --> void" << "QQuickWebView.navigationRequested(QWebNavigationRequest*) --> void" - << "QQuickWebView.load(QUrl) --> void" << "QQuickWebView.loadHtml(QString,QUrl) --> void" << "QQuickWebView.loadHtml(QString) --> void" << "QQuickWebView.goBack() --> void" << "QQuickWebView.goForward() --> void" << "QQuickWebView.stop() --> void" << "QQuickWebView.reload() --> void" + << "QWebLoadRequest.url --> QUrl" + << "QWebLoadRequest.status --> QQuickWebView::LoadStatus" + << "QWebLoadRequest.errorString --> QString" + << "QWebLoadRequest.errorDomain --> QQuickWebView::ErrorDomain" + << "QWebLoadRequest.errorCode --> int" << "QWebNavigationRequest.url --> QUrl" - << "QWebNavigationRequest.originatingUrl --> QUrl" - << "QWebNavigationRequest.button --> int" - << "QWebNavigationRequest.modifiers --> int" - << "QWebNavigationRequest.action --> int" + << "QWebNavigationRequest.mouseButton --> int" + << "QWebNavigationRequest.keyboardModifiers --> int" + << "QWebNavigationRequest.action --> QQuickWebView::NavigationRequestAction" << "QWebNavigationRequest.navigationType --> QQuickWebView::NavigationType" << "QWebNavigationRequest.actionChanged() --> void" ; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro index 8b5b3cbb8..9d16a7bdd 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro @@ -3,7 +3,7 @@ SOURCES += tst_qmltests.cpp TARGET = tst_qmltests_DesktopBehavior OBJECTS_DIR = obj_DesktopBehavior/$$activeBuildConfig() -CONFIG += qtwebkit-private +QT += webkit-private CONFIG += warn_on testcase QT -= testlib diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml index 432416a63..18763bfef 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml @@ -2,10 +2,11 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" // FIXME: Moved to Desktop tests because we want to have mouseClick() to open the <select> tag. We can move it back // when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083. -WebView { +TestWebView { id: webView width: 400 @@ -37,12 +38,6 @@ WebView { } SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: titleSpy target: webView signalName: "titleChanged" @@ -58,9 +53,8 @@ WebView { webView.finalSelection = -1 webView.useAcceptDirectly = false webView.selectorLoaded = false - loadSpy.clear() - webView.load(Qt.resolvedUrl("../common/select.html")) - loadSpy.wait() + webView.url = Qt.resolvedUrl("../common/select.html") + verify(webView.waitForLoadSucceeded()) titleSpy.clear() } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml index b8ab29496..e035dc2a9 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 200 height: 400 @@ -17,15 +18,9 @@ WebView { signalName: "linkHovered" } - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - onLinkHovered: { - webView.lastUrl = url - webView.lastTitle = title + webView.lastUrl = hoveredUrl + webView.lastTitle = hoveredTitle } TestCase { @@ -48,8 +43,8 @@ WebView { function test_linkHovered() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/test2.html")) - loadSpy.wait() + webView.url = Qt.resolvedUrl("../common/test2.html") + verify(webView.waitForLoadSucceeded()) mouseMove(webView, 100, 100) spy.wait() compare(spy.count, 1) @@ -64,8 +59,8 @@ WebView { function test_linkHoveredDoesntEmitRepeated() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/test2.html")) - loadSpy.wait() + webView.url = Qt.resolvedUrl("../common/test2.html") + verify(webView.waitForLoadSucceeded()) for (var i = 0; i < 100; i += 10) mouseMove(webView, 100, 100 + i) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml index 9e173d56a..b50aec371 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 200 height: 400 @@ -11,19 +12,13 @@ WebView { property string lastUrl SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: linkHoveredSpy target: webView signalName: "linkHovered" } onLinkHovered: { - webView.lastUrl = url + webView.lastUrl = hoveredUrl } TestCase { @@ -41,15 +36,13 @@ WebView { function init() { webView.lastUrl = "" linkHoveredSpy.clear() - loadSpy.clear() } function test_baseUrlAfterLoadHtml() { - loadSpy.clear() linkHoveredSpy.clear() compare(linkHoveredSpy.count, 0) webView.loadHtml("<html><head><title>Test page with huge link area</title></head><body><a title=\"A title\" href=\"test1.html\"><img width=200 height=200></a></body></html>", "http://www.example.foo.com") - loadSpy.wait() + verify(webView.waitForLoadSucceeded()) compare("http://www.example.foo.com/", webView.url) mouseMove(webView, 100, 100) linkHoveredSpy.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml index eb18a8216..1b3ab6314 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml @@ -2,9 +2,10 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" Item { - WebView { + TestWebView { id: webView property variant lastMessage experimental.preferences.navigatorQtObjectEnabled: true @@ -13,7 +14,7 @@ Item { } } - WebView { + TestWebView { id: otherWebView property variant lastMessage experimental.preferences.navigatorQtObjectEnabled: true @@ -22,7 +23,7 @@ Item { } } - WebView { + TestWebView { id: disabledWebView property bool receivedMessage experimental.preferences.navigatorQtObjectEnabled: false @@ -32,51 +33,31 @@ Item { } SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: messageSpy target: webView.experimental signalName: "messageReceived" } SignalSpy { - id: otherLoadSpy - target: otherWebView - signalName: "loadSucceeded" - } - - SignalSpy { id: otherMessageSpy target: otherWebView.experimental signalName: "messageReceived" } - SignalSpy { - id: disabledWebViewLoadSpy - target: disabledWebView - signalName: "loadSucceeded" - } - TestCase { name: "DesktopWebViewMessaging" property url testUrl: Qt.resolvedUrl("../common/messaging.html") function init() { - loadSpy.clear() messageSpy.clear() webView.lastMessage = null - otherLoadSpy.clear() otherMessageSpy.clear() otherWebView.lastMessage = null } function test_basic() { - webView.load(testUrl) - loadSpy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) webView.experimental.postMessage("HELLO") messageSpy.wait() compare(webView.lastMessage.data, "OLLEH") @@ -84,10 +65,10 @@ Item { } function test_twoWebViews() { - webView.load(testUrl) - otherWebView.load(testUrl) - loadSpy.wait() - otherLoadSpy.wait() + webView.url = testUrl + otherWebView.url = testUrl + verify(webView.waitForLoadSucceeded()) + verify(otherWebView.waitForLoadSucceeded()) webView.experimental.postMessage("FIRST") otherWebView.experimental.postMessage("SECOND") messageSpy.wait() @@ -97,9 +78,9 @@ Item { } function test_disabled() { - disabledWebView.load(testUrl) + disabledWebView.url = testUrl verify(!disabledWebView.experimental.preferences.navigatorQtObjectEnabled) - disabledWebViewLoadSpy.wait() + verify(disabledWebView.waitForLoadSucceeded()) disabledWebView.experimental.postMessage("HI") wait(1000) verify(!disabledWebView.receivedMessage) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml index 169a0273e..2aefce537 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml @@ -2,16 +2,16 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" Item { property int expectedLength: 0 property int totalBytes: 0 property bool shouldDownload: false - property string originatingUrl: "" property url beginUrl: Qt.resolvedUrl("../common/test2.html") property url endUrl: Qt.resolvedUrl("../common/test1.html") - WebView { + TestWebView { id: webView width: 200 height: 200 @@ -21,11 +21,10 @@ Item { onNavigationRequested: { if (shouldDownload) request.action = WebViewExperimental.DownloadRequest - else if (request.button == Qt.MiddleButton && request.modifiers & Qt.ControlModifier) { - otherWebView.load(request.url) + else if (request.mouseButton == Qt.MiddleButton && request.keyboardModifiers & Qt.ControlModifier) { + otherWebView.url = request.url request.action = WebView.IgnoreRequest } - originatingUrl = request.originatingUrl } experimental.onDownloadRequested: { @@ -45,23 +44,11 @@ Item { } } - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - WebView { + TestWebView { id: otherWebView } SignalSpy { - id: otherSpy - target: otherWebView - signalName: "loadSucceeded" - } - - SignalSpy { id: downloadSpy target: webView.experimental signalName: "downloadRequested" @@ -86,45 +73,34 @@ Item { } function init() { - spy.clear() - otherSpy.clear() downloadSpy.clear() downloadFinishedSpy.clear() shouldDownload = false - originatingUrl = "" } function test_usePolicy() { - webView.load(beginUrl) - spy.wait() - spy.clear() + webView.url = beginUrl + verify(webView.waitForLoadSucceeded()) mouseClick(webView, 100, 100, Qt.LeftButton) - spy.wait() - compare(spy.count, 1) + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Test page 1") compare(webView.url, endUrl) } function test_ignorePolicy() { - webView.load(beginUrl) - spy.wait() - spy.clear() - compare(spy.count, 0) - compare(otherSpy.count, 0) + webView.url = beginUrl + verify(webView.waitForLoadSucceeded()) mouseClick(webView, 100, 100, Qt.MiddleButton, Qt.ControlModifier) - otherSpy.wait() - compare(spy.count, 0) - compare(otherSpy.count, 1) + verify(otherWebView.waitForLoadSucceeded()) + verify(webView.loadStatus == null) compare(webView.url, beginUrl) compare(otherWebView.title, "Test page 1") compare(otherWebView.url, endUrl) } function test_downloadPolicy() { - webView.load(beginUrl) - spy.wait() - spy.clear() - compare(spy.count, 0) + webView.url = beginUrl + verify(webView.waitForLoadSucceeded()) downloadSpy.clear() downloadFinishedSpy.clear() expectedLength = 0 @@ -136,16 +112,5 @@ Item { compare(downloadFinishedSpy.count, 1) compare(totalBytes, expectedLength) } - - function test_originatingUrl() { - webView.load(beginUrl) - spy.wait() - spy.clear() - mouseClick(webView, 100, 100, Qt.LeftButton) - spy.wait() - compare(webView.title, "Test page 1") - compare(webView.url, endUrl) - compare(originatingUrl, beginUrl) - } } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro index 7f4e3d12f..57307f07a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro @@ -3,7 +3,7 @@ SOURCES += tst_qmltests.cpp TARGET = tst_qmltests_WebView OBJECTS_DIR = obj_WebView/$$activeBuildConfig() -CONFIG += qtwebkit-private +QT += webkit-private CONFIG += warn_on testcase QT -= testlib diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml index 8bcb5eccb..875bcd060 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml @@ -78,7 +78,7 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "applicationScheme://something" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Test Application Scheme") } @@ -88,12 +88,12 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "scheme2://some-url-string" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme2 Reply") testUrl = "scheme1://some-url-string" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme1 Reply") @@ -104,12 +104,12 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "scheme3://url1" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme3 Reply1") testUrl = "scheme3://url2" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme3 Reply2") @@ -120,12 +120,12 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "schemeCharset://latin1" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "title with copyright ©") testUrl = "schemeCharset://utf-8" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "title with copyright ©") } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml index f8324a606..9f1d43231 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml @@ -61,14 +61,14 @@ WebView { function test_downloadRequest() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/download.zip")) + webView.url = Qt.resolvedUrl("../common/download.zip") spy.wait() compare(spy.count, 1) } function test_expectedLength() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/download.zip")) + webView.url = Qt.resolvedUrl("../common/download.zip") spy.wait() compare(spy.count, 1) compare(expectedLength, 325) @@ -76,7 +76,7 @@ WebView { function test_succeeded() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/download.zip")) + webView.url = Qt.resolvedUrl("../common/download.zip") spy.wait() compare(spy.count, 1) downloadFinishedSpy.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml index 121809316..20d538fbf 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView SignalSpy { @@ -11,12 +12,6 @@ WebView { signalName: "iconChanged" } - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - Image { id: favicon source: webView.icon @@ -29,18 +24,17 @@ WebView { function init() { if (webView.icon != '') { // If this is not the first test, then load a blank page without favicon, restoring the initial state. - webView.load('about:blank') + webView.url = 'about:blank' spy.wait() - loadSpy.wait() + verify(webView.waitForLoadSucceeded()) } - loadSpy.clear() spy.clear() } function test_favIconLoad() { compare(spy.count, 0) var url = Qt.resolvedUrl("../common/favicon.html") - webView.load(url) + webView.url = url spy.wait() compare(spy.count, 1) compare(favicon.width, 48) @@ -50,7 +44,7 @@ WebView { function test_favIconLoadEncodedUrl() { compare(spy.count, 0) var url = Qt.resolvedUrl("../common/favicon2.html?favicon=load should work with#whitespace!") - webView.load(url) + webView.url = url spy.wait() compare(spy.count, 1) compare(favicon.width, 16) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml index fd898a78e..41097bbcf 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml @@ -46,7 +46,7 @@ WebView { function test_permissionRequest() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/geolocation.html")) + webView.url = Qt.resolvedUrl("../common/geolocation.html") spy.wait() compare(spy.count, 1) } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml index 13adb3b2d..4e15c2344 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml @@ -2,8 +2,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" -WebView { +TestWebView { id: webView property bool modelMessageEqualsMessage: false @@ -54,12 +55,6 @@ WebView { } } - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - TestCase { id: test name: "WebViewJavaScriptDialogs" @@ -69,55 +64,48 @@ WebView { webView.messageFromAlertDialog = "" webView.confirmCount = 0 webView.promptCount = 0 - loadSpy.clear() } function test_alert() { - webView.load(Qt.resolvedUrl("../common/alert.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/alert.html") + verify(webView.waitForLoadSucceeded()) compare(webView.messageFromAlertDialog, "Hello Qt") verify(webView.modelMessageEqualsMessage) } function test_alertWithoutDialog() { webView.experimental.alertDialog = null - webView.load(Qt.resolvedUrl("../common/alert.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/alert.html") + verify(webView.waitForLoadSucceeded()) compare(webView.messageFromAlertDialog, "") } function test_confirm() { - webView.load(Qt.resolvedUrl("../common/confirm.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/confirm.html") + verify(webView.waitForLoadSucceeded()) compare(webView.confirmCount, 2) compare(webView.title, "ACCEPTED REJECTED") } function test_confirmWithoutDialog() { webView.experimental.confirmDialog = null - webView.load(Qt.resolvedUrl("../common/confirm.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/confirm.html") + verify(webView.waitForLoadSucceeded()) compare(webView.confirmCount, 0) compare(webView.title, "ACCEPTED ACCEPTED") } function test_prompt() { - webView.load(Qt.resolvedUrl("../common/prompt.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/prompt.html") + verify(webView.waitForLoadSucceeded()) compare(webView.promptCount, 2) compare(webView.title, "tQ olleH") } function test_promptWithoutDialog() { webView.experimental.promptDialog = null - webView.load(Qt.resolvedUrl("../common/prompt.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/prompt.html") + verify(webView.waitForLoadSucceeded()) compare(webView.promptCount, 0) compare(webView.title, "FAIL") } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml index 26a42c0b7..51c1f7dd0 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml @@ -1,35 +1,30 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 property variant testUrl - SignalSpy { - id: spy - target: webView - signalName: "loadFailed" - } - TestCase { id: test name: "WebViewLoadFail" function test_fail() { - compare(spy.count, 0) testUrl = Qt.resolvedUrl("file_that_does_not_exist.html") - webView.load(testUrl) - spy.wait() - compare(spy.count, 1) + webView.url = testUrl + verify(webView.waitForLoadFailed()) } } - onLoadFailed: { - test.compare(url, testUrl) - test.compare(errorCode, NetworkReply.ContentNotFoundError) - test.compare(errorDomain, WebView.NetworkErrorDomain) + onLoadingChanged: { + if (loadRequest.status == WebView.LoadFailedStatus) { + test.compare(loadRequest.url, testUrl) + test.compare(loadRequest.errorCode, NetworkReply.ContentNotFoundError) + test.compare(loadRequest.errorDomain, WebView.NetworkErrorDomain) + } } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml index b57df66a6..297c082e5 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml @@ -1,27 +1,20 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 200 height: 400 - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - TestCase { name: "WebViewLoadHtml" function test_loadProgressAfterLoadHtml() { - loadSpy.clear() - compare(loadSpy.count, 0) compare(webView.loadProgress, 0) webView.loadHtml("<html><head><title>Test page 1</title></head><body>Hello.</body></html>") - loadSpy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.loadProgress, 100) } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml index a51d6f69f..2f95ef11d 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml @@ -1,27 +1,21 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - TestCase { name: "WebViewLoadProgress" function test_loadProgress() { - compare(spy.count, 0) compare(webView.loadProgress, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) + webView.url = Qt.resolvedUrl("../common/test1.html") compare(webView.loadProgress, 0) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.loadProgress, 100) } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml index 10ac879a8..620686003 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml @@ -1,19 +1,14 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: spyProgress target: webView signalName: "loadProgressChanged" @@ -25,11 +20,11 @@ WebView { function test_loadProgressSignal() { compare(spyProgress.count, 0) compare(webView.loadProgress, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) + webView.url = Qt.resolvedUrl("../common/test1.html") spyProgress.wait() compare(true, webView.loadProgress > -1 && webView.loadProgress < 101) if (webView.loadProgress > 0 && webView.loadProgress < 100) { - spy.wait() + verify(webView.waitForLoadSucceeded()) spyProgress.wait() compare(webView.loadProgress, 100) } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml index d70976c4a..8fcbae54a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml @@ -1,11 +1,14 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView property variant lastUrl property bool watchProgress: false + property int numLoadStarted: 0 + property int numLoadSucceeded: 0 onLoadProgressChanged: { if (watchProgress && webView.loadProgress != 100) { @@ -14,40 +17,44 @@ WebView { } } - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" + onLoadingChanged: { + if (loadRequest.status == WebView.LoadStartedStatus) + ++numLoadStarted + if (loadRequest.status == WebView.LoadSucceededStatus) + ++numLoadSucceeded } TestCase { id: test name: "WebViewLoadUrl" function test_loadIgnoreEmptyUrl() { - compare(spy.count, 0) var url = Qt.resolvedUrl("../common/test1.html") - webView.load(url) - spy.wait() - compare(spy.count, 1) + webView.url = url + verify(webView.waitForLoadSucceeded()) + compare(numLoadStarted, 1) + compare(numLoadSucceeded, 1) compare(webView.url, url) lastUrl = webView.url - webView.load('') + webView.url = '' wait(1000) - compare(spy.count, 1) + compare(numLoadStarted, 1) + compare(numLoadSucceeded, 1) compare(webView.url, lastUrl) - webView.load('about:blank') - spy.wait() - compare(spy.count, 2) + webView.url = 'about:blank' + verify(webView.waitForLoadSucceeded()) + compare(numLoadStarted, 2) + compare(numLoadSucceeded, 2) compare(webView.url, 'about:blank') // It shouldn't interrupt any ongoing load when an empty url is used. watchProgress = true - webView.load(url) - spy.wait() - compare(spy.count, 3) + webView.url = url + webView.waitForLoadSucceeded() + compare(numLoadStarted, 3) + compare(numLoadSucceeded, 3) verify(!watchProgress) compare(webView.url, url) } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml index b886e48f3..3b51c9cc1 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml @@ -2,18 +2,13 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - ListView { id: backItemsList anchors.fill: parent @@ -40,64 +35,56 @@ WebView { name: "WebViewNavigationHistory" function test_navigationHistory() { - compare(spy.count, 0) compare(webView.loadProgress, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/test1.html") + verify(webView.waitForLoadSucceeded()) compare(webView.canGoBack, false) compare(webView.canGoForward, false) compare(backItemsList.count, 0) compare(forwardItemsList.count, 0) - spy.clear() - webView.load(Qt.resolvedUrl("../common/test2.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/test2.html") + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test2.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 1) - spy.clear() webView.experimental.goBackTo(0) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test1.html")) compare(webView.canGoBack, false) compare(webView.canGoForward, true) compare(backItemsList.count, 0) compare(forwardItemsList.count, 1) - spy.clear() webView.goForward() - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test2.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 1) compare(forwardItemsList.count, 0) - spy.clear() - webView.load(Qt.resolvedUrl("../common/javascript.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/javascript.html") + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/javascript.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 2) compare(forwardItemsList.count, 0) - spy.clear() webView.experimental.goBackTo(1) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test1.html")) compare(webView.canGoBack, false) compare(webView.canGoForward, true) compare(backItemsList.count, 0) compare(forwardItemsList.count, 2) - spy.clear() webView.experimental.goForwardTo(1) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/javascript.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 2) compare(forwardItemsList.count, 0) - spy.clear() webView.goBack() - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test2.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, true) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml index 70745d8d6..660ca7326 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml @@ -48,7 +48,7 @@ WebView { function test_permissionRequest() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/geolocation.html")) + webView.url = Qt.resolvedUrl("../common/geolocation.html") spy.wait() compare(spy.count, 1) compare(webView.success, true) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml index 917b689e6..4f356e88b 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml @@ -2,9 +2,10 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" Item { - WebView { + TestWebView { id: webView width: 400 height: 300 @@ -13,19 +14,13 @@ Item { experimental.preferences.localStorageEnabled: true experimental.preferences.pluginsEnabled: true - WebView { + TestWebView { id: webView2 width: 400 height: 300 } SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: titleSpy target: webView signalName: "titleChanged" @@ -85,12 +80,6 @@ Item { signalName: "defaultFixedFontSizeChanged" } - SignalSpy { - id: otherSpy - target: webView2 - signalName: "loadSucceeded" - } - TestCase { name: "WebViewPreferences" @@ -132,9 +121,8 @@ Item { webView.experimental.preferences.defaultFixedFontSize = defaultFixedFontSize if (webView.url != '' && webView.url != 'about:blank') { - spy.clear() - webView.load('about:blank') - spy.wait() + webView.url = 'about:blank' + verify(webView.waitForLoadSucceeded()) } standardFontFamilySpy.clear() @@ -151,42 +139,40 @@ Item { webView.experimental.preferences.javascriptEnabled = true webView.experimental.preferences.localStorageEnabled = true webView.experimental.preferences.pluginsEnabled = true - spy.clear() titleSpy.clear() } function test_javascriptEnabled() { webView.experimental.preferences.javascriptEnabled = true var testUrl = Qt.resolvedUrl("../common/javascript.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "New Title") } function test_javascriptDisabled() { webView.experimental.preferences.javascriptEnabled = false var testUrl = Qt.resolvedUrl("../common/javascript.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Original Title") } function test_localStorageDisabled() { webView.experimental.preferences.localStorageEnabled = false var testUrl = Qt.resolvedUrl("../common/localStorage.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Original Title") } function test_localStorageEnabled() { webView.experimental.preferences.localStorageEnabled = true var testUrl = Qt.resolvedUrl("../common/localStorage.html") - webView.load(testUrl) - spy.wait() - spy.clear() - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "New Title") } @@ -194,26 +180,24 @@ Item { webView.experimental.preferences.javascriptEnabled = true webView2.experimental.preferences.javascriptEnabled = true var testUrl = Qt.resolvedUrl("../common/javascript.html") - webView.load(testUrl) - spy.wait() - webView2.load(testUrl) - otherSpy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + webView2.url = testUrl + verify(webView2.waitForLoadSucceeded()) compare(webView.title, "New Title") compare(webView2.title, "New Title") - spy.clear() - otherSpy.clear() webView.experimental.preferences.javascriptEnabled = false - webView.load(testUrl) - spy.wait() - webView2.load(testUrl) - otherSpy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + webView2.url = testUrl + verify(webView2.waitForLoadSucceeded()) compare(webView.title, "Original Title") compare(webView2.title, "New Title") } function test_standardFontFamilyChanged() { var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-family") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -222,7 +206,7 @@ Item { webView.experimental.preferences.standardFontFamily = "foobar" standardFontFamilySpy.wait() compare(standardFontFamilySpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -231,7 +215,7 @@ Item { function test_fontSizeChanged() { var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -240,7 +224,7 @@ Item { webView.experimental.preferences.defaultFontSize = defaultFontSize + 1 defaultFontSizeSpy.wait() compare(defaultFontSizeSpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -249,7 +233,7 @@ Item { function test_fixedFontSizeChanged() { var url = Qt.resolvedUrl("../common/font-preferences.html?fixed#font-size") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -258,13 +242,13 @@ Item { webView.experimental.preferences.defaultFixedFontSize = defaultFixedFontSize + 1 defaultFixedFontSizeSpy.wait() compare(defaultFixedFontSizeSpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() compare(webView.title, (defaultFixedFontSize + 1).toString() + "px") - webView.load(Qt.resolvedUrl("../common/font-preferences.html?standard#font-size")) + webView.url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size") titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -274,7 +258,7 @@ Item { function test_minimumFontSizeChanged() { verify(defaultMinimumFontSize < defaultFontSize) var url = Qt.resolvedUrl("../common/font-preferences.html?minimum#font-size") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -286,7 +270,7 @@ Item { webView.experimental.preferences.minimumFontSize = defaultFontSize minimumFontSizeSpy.wait() compare(minimumFontSizeSpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml index 4761cd322..036ee9d86 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml @@ -1,33 +1,26 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - TestCase { name: "WebViewProperties" function test_title() { - compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/test1.html") + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Test page 1") } function test_url() { - compare(spy.count, 1) var testUrl = Qt.resolvedUrl("../common/test1.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.url, testUrl) } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml index f36ea8579..04f2c7e13 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml @@ -1,19 +1,14 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: spyTitle target: webView signalName: "titleChanged" @@ -25,7 +20,8 @@ WebView { function test_titleFirstLoad() { compare(spyTitle.count, 0) var testUrl = Qt.resolvedUrl("../common/test3.html") - webView.load(testUrl) + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) spyTitle.wait() compare(webView.title, "Test page 3") spyTitle.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/TestWebView.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/TestWebView.qml new file mode 100644 index 000000000..aa0baae4f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/TestWebView.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 + +WebView { + property var loadStatus: null + + function waitForLoadSucceeded() { + var timeout = 5000 + var i = 0 + while (i < timeout && loadStatus != WebView.LoadSucceededStatus) { + testResult.wait(50) + i += 50 + } + var success = loadStatus == WebView.LoadSucceededStatus + loadStatus = null + return success + } + function waitForLoadFailed() { + var timeout = 5000 + var i = 0 + while (i < timeout && loadStatus != WebView.LoadFailedStatus) { + testResult.wait(50) + i += 50 + } + var failure = loadStatus == WebView.LoadFailedStatus + loadStatus = null + return failure + } + + TestResult { id: testResult } + + onLoadingChanged: loadStatus = loadRequest.status +} + diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp index bcc246db4..782b041ca 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp @@ -20,7 +20,7 @@ #include "../bytearraytestdata.h" #include "../util.h" -#include "qquickwebview_p.h" +#include "private/qquickwebview_p.h" #include <QGuiApplication> #include <QVarLengthArray> #include <QtQuickTest/quicktest.h> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro index 25cd8324f..4a8d86f80 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro @@ -1,4 +1,4 @@ include(../tests.pri) SOURCES += $${TARGET}.cpp -CONFIG += qtwebkit-private +QT += webkit-private DEFINES += IMPORT_DIR=\"\\\"$${ROOT_BUILD_DIR}$${QMAKE_DIR_SEP}imports\\\"\" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp index 12886b314..a6b13990a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp @@ -23,8 +23,9 @@ #include <QDeclarativeEngine> #include <QScopedPointer> #include <QtTest/QtTest> -#include <qquickwebpage_p.h> -#include <qquickwebview_p.h> +#include <private/qquickwebpage_p.h> +#include <private/qquickwebview_p.h> +#include <private/qwebloadrequest_p.h> class tst_QQuickWebView : public QObject { Q_OBJECT @@ -54,6 +55,7 @@ private slots: void removeFromCanvas(); void multipleWebViewWindows(); void multipleWebViews(); + void transparentWebViews(); private: void prepareWebViewComponent(); @@ -120,8 +122,6 @@ void tst_QQuickWebView::navigationStatusAtStartup() QCOMPARE(webView()->canGoForward(), false); QCOMPARE(webView()->loading(), false); - - QCOMPARE(webView()->canReload(), false); } class LoadStartedCatcher : public QObject { @@ -130,15 +130,17 @@ public: LoadStartedCatcher(QQuickWebView* webView) : m_webView(webView) { - connect(m_webView, SIGNAL(loadStarted()), this, SLOT(onLoadStarted())); + connect(m_webView, SIGNAL(loadingChanged(QWebLoadRequest*)), this, SLOT(onLoadingChanged(QWebLoadRequest*))); } public slots: - void onLoadStarted() + void onLoadingChanged(QWebLoadRequest* loadRequest) { - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + if (loadRequest->status() == QQuickWebView::LoadStartedStatus) { + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - QCOMPARE(m_webView->loading(), true); + QCOMPARE(m_webView->loading(), true); + } } signals: @@ -153,12 +155,12 @@ void tst_QQuickWebView::stopEnabledAfterLoadStarted() QCOMPARE(webView()->loading(), false); LoadStartedCatcher catcher(webView()); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); waitForSignal(&catcher, SIGNAL(finished())); QCOMPARE(webView()->loading(), true); - waitForSignal(webView(), SIGNAL(loadSucceeded())); + QVERIFY(waitForLoadSucceeded(webView())); } void tst_QQuickWebView::baseUrl() @@ -169,8 +171,8 @@ void tst_QQuickWebView::baseUrl() void tst_QQuickWebView::loadEmptyUrl() { - webView()->load(QUrl()); - webView()->load(QUrl(QLatin1String(""))); + webView()->setUrl(QUrl()); + webView()->setUrl(QUrl(QLatin1String(""))); } void tst_QQuickWebView::loadEmptyPageViewVisible() @@ -181,64 +183,64 @@ void tst_QQuickWebView::loadEmptyPageViewVisible() void tst_QQuickWebView::loadEmptyPageViewHidden() { - QSignalSpy loadStartedSpy(webView(), SIGNAL(loadStarted())); + QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebLoadRequest*))); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); - QCOMPARE(loadStartedSpy.size(), 1); + QCOMPARE(loadSpy.size(), 2); } void tst_QQuickWebView::loadNonexistentFileUrl() { - QSignalSpy loadFailedSpy(webView(), SIGNAL(loadStarted())); + QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebLoadRequest*))); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadFailed(QQuickWebView::ErrorDomain, int, QUrl, QString)))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); + QVERIFY(waitForLoadFailed(webView())); - QCOMPARE(loadFailedSpy.size(), 1); + QCOMPARE(loadSpy.size(), 2); } void tst_QQuickWebView::backAndForward() { - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); webView()->goBack(); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); webView()->goForward(); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); } void tst_QQuickWebView::reload() { - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); webView()->reload(); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); } void tst_QQuickWebView::stop() { - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); @@ -250,9 +252,9 @@ void tst_QQuickWebView::loadProgress() { QCOMPARE(webView()->loadProgress(), 0); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged(int))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged())); + QVERIFY(waitForLoadSucceeded(webView())); QVERIFY(loadProgressChangedSpy.count() >= 1); @@ -271,8 +273,8 @@ void tst_QQuickWebView::showWebView() { webView()->setSize(QSizeF(300, 400)); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/direct-image-compositing.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/direct-image-compositing.html"))); + QVERIFY(waitForLoadSucceeded(webView())); m_window->show(); // This should not crash. @@ -307,14 +309,14 @@ void tst_QQuickWebView::multipleWebViewWindows() QScopedPointer<TestWindow> window2(new TestWindow(webView2)); webView1->setSize(QSizeF(300, 400)); - webView1->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); - QVERIFY(waitForSignal(webView1, SIGNAL(loadSucceeded()))); + webView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView1)); window1->show(); webView1->setVisible(true); webView2->setSize(QSizeF(300, 400)); - webView2->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView2, SIGNAL(loadSucceeded()))); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2)); window2->show(); webView2->setVisible(true); QTest::qWait(200); @@ -331,23 +333,50 @@ void tst_QQuickWebView::multipleWebViews() webView2->setParentItem(m_window->rootItem()); webView1->setSize(QSizeF(300, 400)); - webView1->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); - QVERIFY(waitForSignal(webView1.data(), SIGNAL(loadSucceeded()))); + webView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView1.data())); webView1->setVisible(true); webView2->setSize(QSizeF(300, 400)); - webView2->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView2.data(), SIGNAL(loadSucceeded()))); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2.data())); webView2->setVisible(true); QTest::qWait(200); } +void tst_QQuickWebView::transparentWebViews() +{ + showWebView(); + + // This should not crash. + QScopedPointer<QQuickWebView> webView1(newWebView()); + webView1->setParentItem(m_window->rootItem()); + QScopedPointer<QQuickWebView> webView2(newWebView()); + webView2->setParentItem(m_window->rootItem()); + QVERIFY(!webView1->experimental()->transparentBackground()); + webView2->experimental()->setTransparentBackground(true); + QVERIFY(webView2->experimental()->transparentBackground()); + + webView1->setSize(QSizeF(300, 400)); + webView1->loadHtml("<html><body bgcolor=\"red\"></body></html>"); + QVERIFY(waitForLoadSucceeded(webView1.data())); + webView1->setVisible(true); + + webView2->setSize(QSizeF(300, 400)); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2.data())); + webView2->setVisible(true); + + QTest::qWait(200); + // FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609. +} + void tst_QQuickWebView::scrollRequest() { webView()->setSize(QSizeF(300, 400)); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView())); // COMPARE with the position requested in the html // Use qRound as that is also used when calculating the position diff --git a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri index faf445397..aa8da8bc9 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri +++ b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri @@ -9,9 +9,7 @@ SOURCES += ../util.cpp \ ../bytearraytestdata.cpp INCLUDEPATH += $$PWD -QT += testlib declarative quick - -CONFIG += qtwebkit +QT += testlib declarative quick webkit DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD\\\" \ QWP_PATH=\\\"$${ROOT_BUILD_DIR}/bin\\\" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.cpp b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp index e230221e6..43a6696ef 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/util.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp @@ -18,6 +18,8 @@ */ #include "util.h" +#include "private/qquickwebview_p.h" +#include "private/qwebloadrequest_p.h" #include <stdio.h> void addQtWebProcessToPath() @@ -50,6 +52,58 @@ bool waitForSignal(QObject* obj, const char* signal, int timeout) return timeoutSpy.isEmpty(); } +class LoadSpy : public QEventLoop { + Q_OBJECT +public: + LoadSpy(QQuickWebView* webView) + { + connect(webView, SIGNAL(loadingChanged(QWebLoadRequest*)), SLOT(onLoadingChanged(QWebLoadRequest*))); + } +signals: + void loadSucceeded(); + void loadFailed(); +private slots: + void onLoadingChanged(QWebLoadRequest* loadRequest) + { + if (loadRequest->status() == QQuickWebView::LoadSucceededStatus) + emit loadSucceeded(); + else if (loadRequest->status() == QQuickWebView::LoadFailedStatus) + emit loadFailed(); + } +}; + +bool waitForLoadSucceeded(QQuickWebView* webView, int timeout) +{ + QEventLoop loop; + LoadSpy loadSpy(webView); + QObject::connect(&loadSpy, SIGNAL(loadSucceeded()), &loop, SLOT(quit())); + QTimer timer; + QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); + if (timeout > 0) { + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(timeout); + } + loop.exec(); + return timeoutSpy.isEmpty(); +} + +bool waitForLoadFailed(QQuickWebView* webView, int timeout) +{ + QEventLoop loop; + LoadSpy loadSpy(webView); + QObject::connect(&loadSpy, SIGNAL(loadFailed()), &loop, SLOT(quit())); + QTimer timer; + QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); + if (timeout > 0) { + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(timeout); + } + loop.exec(); + return timeoutSpy.isEmpty(); +} + static void messageHandler(QtMsgType type, const char* message) { if (type == QtCriticalMsg) { @@ -65,3 +119,5 @@ void suppressDebugOutput() if (qgetenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT").isEmpty()) \ qputenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT", "1"); } + +#include "util.moc" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.h b/Source/WebKit2/UIProcess/API/qt/tests/util.h index 1c052bc9a..f7be8b11e 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/util.h +++ b/Source/WebKit2/UIProcess/API/qt/tests/util.h @@ -22,10 +22,14 @@ #include <QSignalSpy> #include <QTimer> +class QQuickWebView; + #if !defined(TESTS_SOURCE_DIR) #define TESTS_SOURCE_DIR "" #endif void addQtWebProcessToPath(); bool waitForSignal(QObject*, const char* signal, int timeout = 10000); +bool waitForLoadSucceeded(QQuickWebView* webView, int timeout = 10000); +bool waitForLoadFailed(QQuickWebView* webView, int timeout = 10000); void suppressDebugOutput(); |