summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit2/UIProcess/API
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit2/UIProcess/API')
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKAPICast.h5
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKContext.cpp15
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKContextPrivate.h3
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKNativeEvent.h3
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKNotification.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKNotification.h2
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPage.cpp7
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPage.h5
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPreferences.cpp56
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPreferences.h9
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h16
-rw-r--r--Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.cpp37
-rw-r--r--Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h54
-rw-r--r--Source/WebKit2/UIProcess/API/C/soup/WKAPICastSoup.h41
-rw-r--r--Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.cpp38
-rw-r--r--Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.h42
-rw-r--r--Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp52
-rw-r--r--Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h57
-rw-r--r--Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/efl/PageClientImpl.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp262
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h104
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h28
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp14
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitError.h48
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp385
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h78
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h28
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp48
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h27
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp107
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h55
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h29
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp39
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp112
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h27
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp62
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp10
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp29
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h18
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp363
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h77
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h34
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp422
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h75
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp149
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h16
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml3
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt101
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types4
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am14
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp239
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp12
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h20
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp123
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp596
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp257
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp151
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h16
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/webkit2.h6
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list2
-rw-r--r--Source/WebKit2/UIProcess/API/mac/PDFViewController.h2
-rw-r--r--Source/WebKit2/UIProcess/API/mac/PDFViewController.mm62
-rw-r--r--Source/WebKit2/UIProcess/API/mac/PageClientImpl.h14
-rw-r--r--Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm24
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm32
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm20
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKView.mm251
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKViewInternal.h4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp125
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h7
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h7
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp828
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h83
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h125
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp34
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp68
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h10
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h5
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp37
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.h2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html5
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/html/inputmethod.html9
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/inspectorserver.pro4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp183
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml66
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml79
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml40
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml38
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml5
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/multifileupload.html11
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/singlefileupload.html11
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/titleupdate.js15
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp84
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/tests.pri5
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/util.cpp17
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/util.h13
114 files changed, 6187 insertions, 837 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h
index bd3fa2d74..e47b05ff5 100644
--- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h
+++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h
@@ -359,4 +359,9 @@ inline ProxyingRefPtr<WebGrammarDetail> toAPI(const WebCore::GrammarDetail& gram
#if defined(BUILDING_GTK__)
#include "WKAPICastGtk.h"
#endif
+
+#if USE(SOUP)
+#include "WKAPICastSoup.h"
+#endif
+
#endif // WKAPICast_h
diff --git a/Source/WebKit2/UIProcess/API/C/WKContext.cpp b/Source/WebKit2/UIProcess/API/C/WKContext.cpp
index cef897714..8890e801e 100644
--- a/Source/WebKit2/UIProcess/API/C/WKContext.cpp
+++ b/Source/WebKit2/UIProcess/API/C/WKContext.cpp
@@ -235,21 +235,6 @@ void WKContextSetLocalStorageDirectory(WKContextRef contextRef, WKStringRef loca
toImpl(contextRef)->setLocalStorageDirectory(toImpl(localStorageDirectory)->string());
}
-void WKContextSetOverrideWebInspectorBaseDirectory(WKContextRef contextRef, WKStringRef webInspectorBaseDirectory)
-{
- toImpl(contextRef)->setOverrideWebInspectorBaseDirectory(toImpl(webInspectorBaseDirectory)->string());
-}
-
-void WKContextSetOverrideWebInspectorPagePath(WKContextRef contextRef, WKStringRef webInspectorPagePath)
-{
- toImpl(contextRef)->setOverrideWebInspectorPagePath(toImpl(webInspectorPagePath)->string());
-}
-
-void WKContextSetOverrideWebInspectorLocalizedStringsPath(WKContextRef contextRef, WKStringRef webInspectorLocalizedStringsPath)
-{
- toImpl(contextRef)->setOverrideWebInspectorLocalizedStringsPath(toImpl(webInspectorLocalizedStringsPath)->string());
-}
-
void WKContextDisableProcessTermination(WKContextRef contextRef)
{
toImpl(contextRef)->disableProcessTermination();
diff --git a/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h b/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h
index ad69da1de..01dac4b01 100644
--- a/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h
+++ b/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h
@@ -62,9 +62,6 @@ WK_EXPORT void WKContextSetIconDatabasePath(WKContextRef context, WKStringRef ic
// we should really change these settings to be on WebPreferences and changeable at runtime.
WK_EXPORT void WKContextSetDatabaseDirectory(WKContextRef context, WKStringRef databaseDirectory);
WK_EXPORT void WKContextSetLocalStorageDirectory(WKContextRef context, WKStringRef localStorageDirectory);
-WK_EXPORT void WKContextSetOverrideWebInspectorBaseDirectory(WKContextRef context, WKStringRef webInspectorBaseDirectory);
-WK_EXPORT void WKContextSetOverrideWebInspectorPagePath(WKContextRef context, WKStringRef webInspectorPagePath);
-WK_EXPORT void WKContextSetOverrideWebInspectorLocalizedStringsPath(WKContextRef context, WKStringRef webInspectorLocalizedStringsPath);
// FIXME: This is a workaround for testing purposes only and should be removed once a better
// solution has been found for testing.
diff --git a/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h b/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h
index ee0bd1777..f0d39fb5a 100644
--- a/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h
+++ b/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h
@@ -41,6 +41,9 @@ struct NSEvent;
typedef NSEvent *WKNativeEventPtr;
#elif defined(WIN32) || defined(_WIN32)
typedef const struct tagMSG* WKNativeEventPtr;
+#elif defined(BUILDING_GTK__)
+typedef union _GdkEvent GdkEvent;
+typedef const GdkEvent* WKNativeEventPtr;
#else
typedef const void* WKNativeEventPtr;
#endif
diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp
index 5dfcbba29..26700e1aa 100644
--- a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp
+++ b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp
@@ -52,9 +52,9 @@ WKStringRef WKNotificationCopyIconURL(WKNotificationRef notification)
return toCopiedAPI(toImpl(notification)->iconURL());
}
-WKStringRef WKNotificationCopyReplaceID(WKNotificationRef notification)
+WKStringRef WKNotificationCopyTag(WKNotificationRef notification)
{
- return toCopiedAPI(toImpl(notification)->replaceID());
+ return toCopiedAPI(toImpl(notification)->tag());
}
WKSecurityOriginRef WKNotificationGetSecurityOrigin(WKNotificationRef notification)
diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.h b/Source/WebKit2/UIProcess/API/C/WKNotification.h
index 11ea97275..3f4b1a900 100644
--- a/Source/WebKit2/UIProcess/API/C/WKNotification.h
+++ b/Source/WebKit2/UIProcess/API/C/WKNotification.h
@@ -37,7 +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 WKStringRef WKNotificationCopyTag(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 130dd0e45..e5682ca4c 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPage.cpp
+++ b/Source/WebKit2/UIProcess/API/C/WKPage.cpp
@@ -82,6 +82,11 @@ void WKPageLoadPlainTextString(WKPageRef pageRef, WKStringRef plainTextStringRef
toImpl(pageRef)->loadPlainTextString(toWTFString(plainTextStringRef));
}
+void WKPageLoadWebArchiveData(WKPageRef pageRef, WKDataRef webArchiveDataRef)
+{
+ toImpl(pageRef)->loadWebArchiveData(toImpl(webArchiveDataRef));
+}
+
void WKPageStopLoading(WKPageRef pageRef)
{
toImpl(pageRef)->stopLoading();
@@ -456,7 +461,9 @@ void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptio
void WKPageSetPageContextMenuClient(WKPageRef pageRef, const WKPageContextMenuClient* wkClient)
{
+#if ENABLE(CONTEXT_MENUS)
toImpl(pageRef)->initializeContextMenuClient(wkClient);
+#endif
}
void WKPageSetPageFindClient(WKPageRef pageRef, const WKPageFindClient* wkClient)
diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.h b/Source/WebKit2/UIProcess/API/C/WKPage.h
index 05b7aff0c..a6d8a661a 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPage.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPage.h
@@ -71,7 +71,7 @@ typedef void (*WKPageDidChangeBackForwardListCallback)(WKPageRef page, WKBackFor
typedef bool (*WKPageShouldGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, const void *clientInfo);
typedef void (*WKPageDidFailToInitializePluginCallback)(WKPageRef page, WKStringRef mimeType, const void* clientInfo);
typedef void (*WKPageDidNewFirstVisuallyNonEmptyLayoutCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo);
-typedef void (*WKPageWillGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, const void *clientInfo);
+typedef void (*WKPageWillGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, WKTypeRef userData, const void *clientInfo);
struct WKPageLoaderClient {
int version;
@@ -113,6 +113,8 @@ struct WKPageLoaderClient {
WKPageDidNewFirstVisuallyNonEmptyLayoutCallback didNewFirstVisuallyNonEmptyLayout;
WKPageWillGoToBackForwardListItemCallback willGoToBackForwardListItem;
+
+ WKPageCallback interactionOccurredWhileProcessUnresponsive;
};
typedef struct WKPageLoaderClient WKPageLoaderClient;
@@ -319,6 +321,7 @@ WK_EXPORT void WKPageLoadURLRequest(WKPageRef page, WKURLRequestRef urlRequest);
WK_EXPORT void WKPageLoadHTMLString(WKPageRef page, WKStringRef htmlString, WKURLRef baseURL);
WK_EXPORT void WKPageLoadAlternateHTMLString(WKPageRef page, WKStringRef htmlString, WKURLRef baseURL, WKURLRef unreachableURL);
WK_EXPORT void WKPageLoadPlainTextString(WKPageRef page, WKStringRef plainTextString);
+WK_EXPORT void WKPageLoadWebArchiveData(WKPageRef page, WKDataRef webArchiveData);
WK_EXPORT void WKPageStopLoading(WKPageRef page);
WK_EXPORT void WKPageReload(WKPageRef page);
diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
index 39903bcb5..a92104dac 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
+++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
@@ -158,6 +158,16 @@ bool WKPreferencesGetJavaEnabled(WKPreferencesRef preferencesRef)
return toImpl(preferencesRef)->javaEnabled();
}
+void WKPreferencesSetJavaEnabledForLocalFiles(WKPreferencesRef preferencesRef, bool javaEnabledForLocalFiles)
+{
+ toImpl(preferencesRef)->setJavaEnabledForLocalFiles(javaEnabledForLocalFiles);
+}
+
+bool WKPreferencesGetJavaEnabledForLocalFiles(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->javaEnabledForLocalFiles();
+}
+
void WKPreferencesSetJavaScriptCanOpenWindowsAutomatically(WKPreferencesRef preferencesRef, bool javaScriptCanOpenWindowsAutomatically)
{
toImpl(preferencesRef)->setJavaScriptCanOpenWindowsAutomatically(javaScriptCanOpenWindowsAutomatically);
@@ -418,6 +428,16 @@ bool WKPreferencesGetCSSRegionsEnabled(WKPreferencesRef preferencesRef)
return toImpl(preferencesRef)->cssRegionsEnabled();
}
+void WKPreferencesSetRegionBasedColumnsEnabled(WKPreferencesRef preferencesRef, bool flag)
+{
+ toImpl(preferencesRef)->setRegionBasedColumnsEnabled(flag);
+}
+
+bool WKPreferencesGetRegionBasedColumnsEnabled(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->regionBasedColumnsEnabled();
+}
+
void WKPreferencesSetNeedsSiteSpecificQuirks(WKPreferencesRef preferencesRef, bool flag)
{
toImpl(preferencesRef)->setNeedsSiteSpecificQuirks(flag);
@@ -678,24 +698,24 @@ bool WKPreferencesGetApplicationChromeModeEnabled(WKPreferencesRef preferencesRe
return toImpl(preferencesRef)->applicationChromeMode();
}
-void WKPreferencesSetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled)
+void WKPreferencesSetInspectorUsesWebKitUserInterface(WKPreferencesRef preferencesRef, bool enabled)
{
- toImpl(preferencesRef)->setSuppressesIncrementalRendering(enabled);
+ toImpl(preferencesRef)->setInspectorUsesWebKitUserInterface(enabled);
}
-bool WKPreferencesGetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef)
+bool WKPreferencesGetInspectorUsesWebKitUserInterface(WKPreferencesRef preferencesRef)
{
- return toImpl(preferencesRef)->suppressesIncrementalRendering();
+ return toImpl(preferencesRef)->inspectorUsesWebKitUserInterface();
}
-void WKPreferencesSetSuppressIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled)
+void WKPreferencesSetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled)
{
- WKPreferencesSetSuppressesIncrementalRendering(preferencesRef, enabled);
+ toImpl(preferencesRef)->setSuppressesIncrementalRendering(enabled);
}
-bool WKPreferencesGetSuppressIncrementalRendering(WKPreferencesRef preferencesRef)
+bool WKPreferencesGetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef)
{
- return WKPreferencesGetSuppressesIncrementalRendering(preferencesRef);
+ return toImpl(preferencesRef)->suppressesIncrementalRendering();
}
void WKPreferencesSetBackspaceKeyNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled)
@@ -758,6 +778,26 @@ bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferencesRef)
return toImpl(preferencesRef)->notificationsEnabled();
}
+void WKPreferencesSetShouldRespectImageOrientation(WKPreferencesRef preferencesRef, bool enabled)
+{
+ toImpl(preferencesRef)->setShouldRespectImageOrientation(enabled);
+}
+
+bool WKPreferencesGetShouldRespectImageOrientation(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->shouldRespectImageOrientation();
+}
+
+void WKPreferencesSetRequestAnimationFrameEnabled(WKPreferencesRef preferencesRef, bool flag)
+{
+ toImpl(preferencesRef)->setRequestAnimationFrameEnabled(flag);
+}
+
+bool WKPreferencesGetRequestAnimationFrameEnabled(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->requestAnimationFrameEnabled();
+}
+
void WKPreferencesResetTestRunnerOverrides(WKPreferencesRef preferencesRef)
{
// Currently we reset the overrides on the web process when preferencesDidChange() is called. Since WTR preferences
diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.h b/Source/WebKit2/UIProcess/API/C/WKPreferences.h
index 501c5a5d6..5e885738e 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPreferences.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.h
@@ -172,11 +172,6 @@ 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);
@@ -202,6 +197,10 @@ WK_EXPORT bool WKPreferencesGetShouldDisplayTextDescriptions(WKPreferencesRef pr
WK_EXPORT void WKPreferencesSetNotificationsEnabled(WKPreferencesRef preferencesRef, bool enabled);
WK_EXPORT bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferencesRef);
+// Defaults to false
+WK_EXPORT void WKPreferencesSetShouldRespectImageOrientation(WKPreferencesRef preferencesRef, bool enabled);
+WK_EXPORT bool WKPreferencesGetShouldRespectImageOrientation(WKPreferencesRef preferencesRef);
+
#ifdef __cplusplus
}
#endif
diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h b/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h
index 36950e891..cbe6b4fd6 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h
@@ -95,6 +95,10 @@ WK_EXPORT bool WKPreferencesGetWebGLEnabled(WKPreferencesRef);
WK_EXPORT void WKPreferencesSetCSSRegionsEnabled(WKPreferencesRef, bool flag);
WK_EXPORT bool WKPreferencesGetCSSRegionsEnabled(WKPreferencesRef);
+// Defaults to false
+WK_EXPORT void WKPreferencesSetRegionBasedColumnsEnabled(WKPreferencesRef, bool flag);
+WK_EXPORT bool WKPreferencesGetRegionBasedColumnsEnabled(WKPreferencesRef);
+
// Defaults to false.
WK_EXPORT void WKPreferencesSetNeedsSiteSpecificQuirks(WKPreferencesRef, bool);
WK_EXPORT bool WKPreferencesGetNeedsSiteSpecificQuirks(WKPreferencesRef);
@@ -167,6 +171,18 @@ WK_EXPORT bool WKPreferencesGetMockScrollbarsEnabled(WKPreferencesRef preference
WK_EXPORT void WKPreferencesSetApplicationChromeModeEnabled(WKPreferencesRef preferencesRef, bool enabled);
WK_EXPORT bool WKPreferencesGetApplicationChromeModeEnabled(WKPreferencesRef preferencesRef);
+// Defaults to false.
+WK_EXPORT void WKPreferencesSetInspectorUsesWebKitUserInterface(WKPreferencesRef preferencesRef, bool enabled);
+WK_EXPORT bool WKPreferencesGetInspectorUsesWebKitUserInterface(WKPreferencesRef preferencesRef);
+
+// Defaults to true.
+WK_EXPORT void WKPreferencesSetJavaEnabledForLocalFiles(WKPreferencesRef preferences, bool javaEnabled);
+WK_EXPORT bool WKPreferencesGetJavaEnabledForLocalFiles(WKPreferencesRef preferences);
+
+// Defaults to true.
+WK_EXPORT void WKPreferencesSetRequestAnimationFrameEnabled(WKPreferencesRef, bool);
+WK_EXPORT bool WKPreferencesGetRequestAnimationFrameEnabled(WKPreferencesRef);
+
WK_EXPORT void WKPreferencesResetTestRunnerOverrides(WKPreferencesRef preferencesRef);
#ifdef __cplusplus
diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.cpp b/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.cpp
new file mode 100644
index 000000000..2b29a2b76
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WKFullScreenClientGtk.h"
+
+#include "WKAPICast.h"
+#include "WebKitWebViewBasePrivate.h"
+
+using namespace WebKit;
+
+void WKViewSetFullScreenClientGtk(WKViewRef viewRef, const WKFullScreenClientGtk* wkClient)
+{
+ webkitWebViewBaseInitializeFullScreenClient(toImpl(viewRef), wkClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h b/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h
new file mode 100644
index 000000000..a8c92166b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKFullScreenClientGtk_h
+#define WKFullScreenClientGtk_h
+
+#include <WebKit2/WKBase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef bool (*WKFullScreenClientGtkWillEnterFullScreenCallback)(const void* clientInfo);
+typedef bool (*WKFullScreenClientGtkWillExitFullScreenCallback)(const void* clientInfo);
+
+struct WKFullScreenClientGtk {
+ int version;
+ const void* clientInfo;
+ WKFullScreenClientGtkWillEnterFullScreenCallback willEnterFullScreen;
+ WKFullScreenClientGtkWillExitFullScreenCallback willExitFullScreen;
+};
+typedef struct WKFullScreenClientGtk WKFullScreenClientGtk;
+
+enum { kWKFullScreenClientGtkCurrentVersion = 0 };
+
+WK_EXPORT void WKViewSetFullScreenClientGtk(WKViewRef viewRef, const WKFullScreenClientGtk* client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKFullScreenClientGtk_h */
diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKAPICastSoup.h b/Source/WebKit2/UIProcess/API/C/soup/WKAPICastSoup.h
new file mode 100644
index 000000000..c8a954460
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/soup/WKAPICastSoup.h
@@ -0,0 +1,41 @@
+/*
+ * Portions Copyright (c) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKAPICastSoup_h
+#define WKAPICastSoup_h
+
+#ifndef WKAPICast_h
+#error "Please #include \"WKAPICast.h\" instead of this file directly."
+#endif
+
+namespace WebKit {
+
+class WebSoupRequestManagerProxy;
+
+WK_ADD_API_MAPPING(WKSoupRequestManagerRef, WebSoupRequestManagerProxy)
+
+}
+
+#endif // WKAPICastSoup_h
diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.cpp b/Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.cpp
new file mode 100644
index 000000000..e4e88d384
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTAwBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WKContextSoup.h"
+
+#include "WKAPICast.h"
+#include "WebContext.h"
+
+using namespace WebKit;
+
+WKSoupRequestManagerRef WKContextGetSoupRequestManager(WKContextRef contextRef)
+{
+ return toAPI(toImpl(contextRef)->soupRequestManagerProxy());
+}
+
diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.h b/Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.h
new file mode 100644
index 000000000..36954ffe3
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/soup/WKContextSoup.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKContextSoup_h
+#define WKContextSoup_h
+
+#include <WebKit2/WKBase.h>
+#include <WebKit2/WKSoupRequestManager.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WK_EXPORT WKSoupRequestManagerRef WKContextGetSoupRequestManager(WKContextRef context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKContextSoup_h */
diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp b/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp
new file mode 100644
index 000000000..187d7fd9c
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WKSoupRequestManager.h"
+
+#include "WKAPICast.h"
+#include "WebSoupRequestManagerProxy.h"
+
+using namespace WebKit;
+
+WKTypeID WKSoupRequestManagerGetTypeID()
+{
+ return toAPI(WebSoupRequestManagerProxy::APIType);
+}
+
+void WKSoupRequestManagerSetClient(WKSoupRequestManagerRef soupRequestManagerRef, const WKSoupRequestManagerClient* wkClient)
+{
+ toImpl(soupRequestManagerRef)->initializeClient(wkClient);
+}
+
+void WKSoupRequestManagerRegisterURIScheme(WKSoupRequestManagerRef soupRequestManagerRef, WKStringRef schemeRef)
+{
+ toImpl(soupRequestManagerRef)->registerURIScheme(toImpl(schemeRef)->string());
+}
+
+void WKSoupRequestManagerHandleURIRequest(WKSoupRequestManagerRef soupRequestManagerRef, WKDataRef data, WKStringRef mimeTypeRef, uint64_t requestID)
+{
+ toImpl(soupRequestManagerRef)->handleURIRequest(toImpl(data), toImpl(mimeTypeRef)->string(), requestID);
+}
diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h b/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h
new file mode 100644
index 000000000..74b4fa005
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKSoupRequestManager_h
+#define WKSoupRequestManager_h
+
+#include "WKAPICast.h"
+#include <WebKit2/WKBase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*WKSoupRequestManagerDidReceiveURIRequestCallback)(WKSoupRequestManagerRef soupRequestManagerRef, WKURLRef urlRef, uint64_t requestID, const void* clientInfo);
+
+struct WKSoupRequestManagerClient {
+ int version;
+ const void* clientInfo;
+ WKSoupRequestManagerDidReceiveURIRequestCallback didReceiveURIRequest;
+};
+typedef struct WKSoupRequestManagerClient WKSoupRequestManagerClient;
+
+enum { kWKSoupRequestManagerClientCurrentVersion = 0 };
+
+WK_EXPORT WKTypeID WKSoupRequestManagerGetTypeID();
+
+WK_EXPORT void WKSoupRequestManagerSetClient(WKSoupRequestManagerRef, const WKSoupRequestManagerClient* client);
+WK_EXPORT void WKSoupRequestManagerRegisterURIScheme(WKSoupRequestManagerRef, WKStringRef schemeRef);
+WK_EXPORT void WKSoupRequestManagerHandleURIRequest(WKSoupRequestManagerRef, WKDataRef, WKStringRef mimeTypeRef, uint64_t requestID);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKSoupRequestManager_h */
diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp
index c21162903..c7e5f029c 100644
--- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp
+++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp
@@ -131,7 +131,7 @@ void PageClientImpl::setCursorHiddenUntilMouseMoves(bool)
notImplemented();
}
-void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportArguments&)
+void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&)
{
notImplemented();
}
diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h
index 40af3b23f..0858fc33d 100644
--- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h
+++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h
@@ -65,7 +65,7 @@ private:
virtual void setCursor(const WebCore::Cursor&);
virtual void setCursorHiddenUntilMouseMoves(bool);
- virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
+ virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&);
virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo);
virtual void clearAllEditCommands();
diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
index 9fadbeab5..8fbfe73f6 100644
--- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
@@ -39,7 +39,9 @@
#include "WebPageProxy.h"
#include "WebPopupMenuProxyGtk.h"
#include <WebCore/Cursor.h>
+#include <WebCore/EventNames.h>
#include <WebCore/GtkUtilities.h>
+#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
using namespace WebCore;
@@ -156,7 +158,7 @@ void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
notImplemented();
}
-void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportArguments&)
+void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&)
{
notImplemented();
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
index 6a1cb2459..54ad99f8f 100644
--- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
+++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
@@ -69,7 +69,7 @@ private:
virtual void toolTipChanged(const WTF::String&, const WTF::String&);
virtual void setCursor(const WebCore::Cursor&);
virtual void setCursorHiddenUntilMouseMoves(bool);
- virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
+ virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&);
virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo);
virtual void clearAllEditCommands();
virtual bool canUndoRedo(WebPageProxy::UndoOrRedo);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
new file mode 100644
index 000000000..b993d2e83
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
@@ -0,0 +1,262 @@
+/*
+ * 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 "WebKitCookieManager.h"
+
+#include "WebKitCookieManagerPrivate.h"
+#include "WebKitEnumTypes.h"
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+enum {
+ CHANGED,
+
+ LAST_SIGNAL
+};
+
+struct _WebKitCookieManagerPrivate {
+ WKRetainPtr<WKCookieManagerRef> wkCookieManager;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE(WebKitCookieManager, webkit_cookie_manager, G_TYPE_OBJECT)
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS, kWKHTTPCookieAcceptPolicyAlways);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER, kWKHTTPCookieAcceptPolicyNever);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY, kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
+
+static void webkit_cookie_manager_init(WebKitCookieManager* manager)
+{
+ WebKitCookieManagerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(manager, WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerPrivate);
+ manager->priv = priv;
+ new (priv) WebKitCookieManagerPrivate();
+}
+
+static void webkitCookieManagerFinalize(GObject* object)
+{
+ WebKitCookieManagerPrivate* priv = WEBKIT_COOKIE_MANAGER(object)->priv;
+ WKCookieManagerStopObservingCookieChanges(priv->wkCookieManager.get());
+ priv->~WebKitCookieManagerPrivate();
+ G_OBJECT_CLASS(webkit_cookie_manager_parent_class)->finalize(object);
+}
+
+static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
+ gObjectClass->finalize = webkitCookieManagerFinalize;
+
+ g_type_class_add_private(findClass, sizeof(WebKitCookieManagerPrivate));
+
+ /**
+ * WebKitCookieManager::changed:
+ * @cookie_manager: the #WebKitCookieManager
+ *
+ * This signal is emitted when cookies are added, removed or modified.
+ */
+ signals[CHANGED] =
+ g_signal_new("changed",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void cookiesDidChange(WKCookieManagerRef, const void* clientInfo)
+{
+ g_signal_emit(WEBKIT_COOKIE_MANAGER(clientInfo), signals[CHANGED], 0);
+}
+
+WebKitCookieManager* webkitCookieManagerCreate(WKCookieManagerRef wkCookieManager)
+{
+ WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, NULL));
+ manager->priv->wkCookieManager = wkCookieManager;
+
+ WKCookieManagerClient wkCookieManagerClient = {
+ kWKCookieManagerClientCurrentVersion,
+ manager, // clientInfo
+ cookiesDidChange
+ };
+ WKCookieManagerSetClient(wkCookieManager, &wkCookieManagerClient);
+ WKCookieManagerStartObservingCookieChanges(wkCookieManager);
+
+ return manager;
+}
+
+/**
+ * webkit_cookie_manager_set_accept_policy:
+ * @cookie_manager: a #WebKitCookieManager
+ * @policy: a #WebKitCookieAcceptPolicy
+ *
+ * Set the cookie acceptance policy of @cookie_manager as @policy.
+ */
+void webkit_cookie_manager_set_accept_policy(WebKitCookieManager* manager, WebKitCookieAcceptPolicy policy)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ WKCookieManagerSetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), policy);
+}
+
+static void webkitCookieManagerGetAcceptPolicyCallback(WKHTTPCookieAcceptPolicy policy, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ g_simple_async_result_set_op_res_gpointer(result.get(), GUINT_TO_POINTER(policy), 0);
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_cookie_manager_get_accept_policy:
+ * @cookie_manager: a #WebKitCookieManager
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously get the cookie acceptance policy of @cookie_manager.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_get_accept_policy_finish() to get the result of the operation.
+ */
+void webkit_cookie_manager_get_accept_policy(WebKitCookieManager* manager, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(manager), callback, userData,
+ reinterpret_cast<gpointer>(webkit_cookie_manager_get_accept_policy));
+ WKCookieManagerGetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetAcceptPolicyCallback);
+}
+
+/**
+ * webkit_cookie_manager_get_accept_policy_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_get_accept_policy().
+ *
+ * Returns: the cookie acceptance policy of @cookie_manager as a #WebKitCookieAcceptPolicy.
+ */
+WebKitCookieAcceptPolicy webkit_cookie_manager_get_accept_policy_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_cookie_manager_get_accept_policy);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
+
+ return static_cast<WebKitCookieAcceptPolicy>(GPOINTER_TO_UINT(g_simple_async_result_get_op_res_gpointer(simpleResult)));
+}
+
+static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomains, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ GPtrArray* domains = g_ptr_array_new_with_free_func(g_free);
+ for (size_t i = 0; i < WKArrayGetSize(wkDomains); ++i) {
+ WKStringRef wkDomain = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkDomains, i));
+ String domain = toImpl(wkDomain)->string();
+ if (domain.isEmpty())
+ continue;
+ g_ptr_array_add(domains, g_strdup(domain.utf8().data()));
+ }
+ g_ptr_array_add(domains, 0);
+ g_simple_async_result_set_op_res_gpointer(result.get(), domains, reinterpret_cast<GDestroyNotify>(g_ptr_array_unref));
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_cookie_manager_get_domains_with_cookies:
+ * @cookie_manager: a #WebKitCookieManager
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously get the list of domains for which @cookie_manager contains cookies.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_get_domains_with_cookies_finish() to get the result of the operation.
+ */
+void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(manager), callback, userData,
+ reinterpret_cast<gpointer>(webkit_cookie_manager_get_domains_with_cookies));
+ WKCookieManagerGetHostnamesWithCookies(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetDomainsWithCookiesCallback);
+}
+
+/**
+ * webkit_cookie_manager_get_domains_with_cookies_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_get_domains_with_cookies().
+ * The return value is a %NULL terminated list of strings which should
+ * be released with g_strfreev().
+ *
+ * Returns: (transfer full) (array zero-terminated=1): A %NULL terminated array of domain names
+ * or %NULL in case of error.
+ */
+gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_cookie_manager_get_domains_with_cookies);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return 0;
+
+ GPtrArray* domains = static_cast<GPtrArray*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return reinterpret_cast<char**>(g_ptr_array_free(domains, FALSE));
+}
+
+/**
+ * webkit_cookie_manager_delete_cookies_for_domain:
+ * @cookie_manager: a #WebKitCookieManager
+ * @domain: a domain name
+ *
+ * Remove all cookies of @cookie_manager for the given @domain.
+ */
+void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manager, const gchar* domain)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+ g_return_if_fail(domain);
+
+ WKRetainPtr<WKStringRef> wkDomain(AdoptWK, WKStringCreateWithUTF8CString(domain));
+ WKCookieManagerDeleteCookiesForHostname(manager->priv->wkCookieManager.get(), wkDomain.get());
+}
+
+/**
+ * webkit_cookie_manager_delete_all_cookies:
+ * @cookie_manager: a #WebKitCookieManager
+ *
+ * Delete all cookies of @cookie_manager
+ */
+void webkit_cookie_manager_delete_all_cookies(WebKitCookieManager* manager)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ WKCookieManagerDeleteAllCookies(manager->priv->wkCookieManager.get());
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
new file mode 100644
index 000000000..791a61d82
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
@@ -0,0 +1,104 @@
+/*
+ * 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 WebKitCookieManager_h
+#define WebKitCookieManager_h
+
+#include <gio/gio.h>
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_COOKIE_MANAGER (webkit_cookie_manager_get_type())
+#define WEBKIT_COOKIE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManager))
+#define WEBKIT_IS_COOKIE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_COOKIE_MANAGER))
+#define WEBKIT_COOKIE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerClass))
+#define WEBKIT_IS_COOKIE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_COOKIE_MANAGER))
+#define WEBKIT_COOKIE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerClass))
+
+typedef struct _WebKitCookieManager WebKitCookieManager;
+typedef struct _WebKitCookieManagerClass WebKitCookieManagerClass;
+typedef struct _WebKitCookieManagerPrivate WebKitCookieManagerPrivate;
+
+/**
+ * WebKitCookieAcceptPolicy:
+ * @WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS: Accept all cookies unconditionally.
+ * @WEBKIT_COOKIE_POLICY_ACCEPT_NEVER: Reject all cookies unconditionally.
+ * @WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY: Accept only cookies set by the main document loaded.
+ *
+ * Enum values used to denote the cookie acceptance policies.
+ */
+typedef enum {
+ WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS,
+ WEBKIT_COOKIE_POLICY_ACCEPT_NEVER,
+ WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY
+} WebKitCookieAcceptPolicy;
+
+struct _WebKitCookieManager {
+ GObject parent;
+
+ WebKitCookieManagerPrivate *priv;
+};
+
+struct _WebKitCookieManagerClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_cookie_manager_get_type (void);
+
+WEBKIT_API void
+webkit_cookie_manager_set_accept_policy (WebKitCookieManager *cookie_manager,
+ WebKitCookieAcceptPolicy policy);
+
+WEBKIT_API void
+webkit_cookie_manager_get_accept_policy (WebKitCookieManager *cookie_manager,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API WebKitCookieAcceptPolicy
+webkit_cookie_manager_get_accept_policy_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gchar **
+webkit_cookie_manager_get_domains_with_cookies_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_delete_cookies_for_domain (WebKitCookieManager *cookie_manager,
+ const gchar *domain);
+
+WEBKIT_API void
+webkit_cookie_manager_delete_all_cookies (WebKitCookieManager *cookie_manager);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h
new file mode 100644
index 000000000..a387af907
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitCookieManagerPrivate_h
+#define WebKitCookieManagerPrivate_h
+
+#include "WebKitCookieManager.h"
+#include "WebKitPrivate.h"
+
+WebKitCookieManager* webkitCookieManagerCreate(WKCookieManagerRef);
+
+#endif // WebKitCookieManagerPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
index 42cf0ab35..daf09ecc2 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
@@ -68,3 +68,17 @@ GQuark webkit_download_error_quark()
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_NETWORK, DownloadErrorNetwork);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, DownloadErrorCancelledByUser);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_DESTINATION, DownloadErrorDestination);
+
+GQuark webkit_print_error_quark()
+{
+ return g_quark_from_static_string(WebCore::errorDomainPrint);
+}
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_GENERAL, PrintErrorGeneral);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND, PrintErrorPrinterNotFound);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE, PrintErrorInvalidPageRange);
+
+GQuark webkit_javascript_error_quark()
+{
+ return g_quark_from_static_string("WebKitJavascriptError");
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h
index 9b0e630c8..c20581683 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h
@@ -29,10 +29,12 @@
G_BEGIN_DECLS
-#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
-#define WEBKIT_POLICY_ERROR webkit_policy_error_quark ()
-#define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark ()
-#define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
+#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
+#define WEBKIT_POLICY_ERROR webkit_policy_error_quark ()
+#define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark ()
+#define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
+#define WEBKIT_PRINT_ERROR webkit_print_error_quark ()
+#define WEBKIT_JAVASCRIPT_ERROR webkit_print_error_quark ()
/**
* WebKitNetworkError:
@@ -104,17 +106,47 @@ typedef enum {
WEBKIT_DOWNLOAD_ERROR_DESTINATION = 401
} WebKitDownloadError;
+/**
+ * WebKitPrintError:
+ * @WEBKIT_PRINT_ERROR_GENERAL: Unspecified error during a print operation
+ * @WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND: Selected printer cannot be found
+ * @WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE: Invalid page range
+ *
+ * Enum values used to denote the various print errors.
+ */
+typedef enum {
+ WEBKIT_PRINT_ERROR_GENERAL = 599,
+ WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND = 500,
+ WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE = 501
+} WebKitPrintError;
+
+/**
+ * WebKitJavascriptError:
+ * @WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED: An exception was raised in Javascript execution
+ *
+ * Enum values used to denote errors happending when executing Javascript
+ */
+typedef enum {
+ WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED = 699
+} WebKitJavascriptError;
+
+WEBKIT_API GQuark
+webkit_network_error_quark (void);
+
+WEBKIT_API GQuark
+webkit_policy_error_quark (void);
+
WEBKIT_API GQuark
-webkit_network_error_quark (void);
+webkit_plugin_error_quark (void);
WEBKIT_API GQuark
-webkit_policy_error_quark (void);
+webkit_download_error_quark (void);
WEBKIT_API GQuark
-webkit_plugin_error_quark (void);
+webkit_print_error_quark (void);
WEBKIT_API GQuark
-webkit_download_error_quark (void);
+webkit_javascript_error_quark (void);
G_END_DECLS
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp
new file mode 100644
index 000000000..96b87a3ba
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp
@@ -0,0 +1,385 @@
+/*
+ * 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 "WebKitFileChooserRequest.h"
+
+#include "WebKitFileChooserRequestPrivate.h"
+#include "WebOpenPanelParameters.h"
+#include <WebCore/FileSystem.h>
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitFileChooserRequest
+ * @Short_description: A request to open a file chooser
+ * @Title: WebKitFileChooserRequest
+ * @See_also: #WebKitWebView
+ *
+ * Whenever the user interacts with an &lt;input type='file' /&gt;
+ * HTML element, WebKit will need to show a dialog to choose one or
+ * more files to be uploaded to the server along with the rest of the
+ * form data. For that to happen in a general way, instead of just
+ * opening a #GtkFileChooserDialog (which might be not desirable in
+ * some cases, which could prefer to use their own file chooser
+ * dialog), WebKit will fire the #WebKitWebView::run-file-chooser
+ * signal with a #WebKitFileChooserRequest object, which will allow
+ * the client application to specify the files to be selected, to
+ * inspect the details of the request (e.g. if multiple selection
+ * should be allowed) and to cancel the request, in case nothing was
+ * selected.
+ *
+ * In case the client application does not wish to handle this signal,
+ * WebKit will provide a default handler which will asynchronously run
+ * a regular #GtkFileChooserDialog for the user to interact with.
+ */
+G_DEFINE_TYPE(WebKitFileChooserRequest, webkit_file_chooser_request, G_TYPE_OBJECT)
+
+struct _WebKitFileChooserRequestPrivate {
+ WKRetainPtr<WKOpenPanelParametersRef> wkParameters;
+ WKRetainPtr<WKOpenPanelResultListenerRef> wkListener;
+ GRefPtr<GtkFileFilter> filter;
+ GRefPtr<GPtrArray> mimeTypes;
+ GRefPtr<GPtrArray> selectedFiles;
+ bool handledRequest;
+};
+
+enum {
+ PROP_0,
+ PROP_FILTER,
+ PROP_MIME_TYPES,
+ PROP_SELECT_MULTIPLE,
+ PROP_SELECTED_FILES,
+};
+
+static void webkit_file_chooser_request_init(WebKitFileChooserRequest* request)
+{
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE(request, WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestPrivate);
+ new (request->priv) WebKitFileChooserRequestPrivate();
+}
+
+static void webkitFileChooserRequestFinalize(GObject* object)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(object);
+
+ // Make sure the request is always handled before finalizing.
+ if (!request->priv->handledRequest)
+ webkit_file_chooser_request_cancel(request);
+
+ request->priv->~WebKitFileChooserRequestPrivate();
+ G_OBJECT_CLASS(webkit_file_chooser_request_parent_class)->finalize(object);
+}
+
+static void webkitFileChooserRequestGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(object);
+ switch (propId) {
+ case PROP_FILTER:
+ g_value_set_object(value, webkit_file_chooser_request_get_mime_types_filter(request));
+ break;
+ case PROP_MIME_TYPES:
+ g_value_set_boxed(value, webkit_file_chooser_request_get_mime_types(request));
+ break;
+ case PROP_SELECT_MULTIPLE:
+ g_value_set_boolean(value, webkit_file_chooser_request_get_select_multiple(request));
+ break;
+ case PROP_SELECTED_FILES:
+ g_value_set_boxed(value, webkit_file_chooser_request_get_selected_files(request));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ break;
+ }
+}
+
+static void webkit_file_chooser_request_class_init(WebKitFileChooserRequestClass* requestClass)
+{
+ GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
+ objectClass->finalize = webkitFileChooserRequestFinalize;
+ objectClass->get_property = webkitFileChooserRequestGetProperty;
+ g_type_class_add_private(requestClass, sizeof(WebKitFileChooserRequestPrivate));
+
+ /**
+ * WebKitFileChooserRequest:filter:
+ *
+ * The filter currently associated with the request. See
+ * webkit_file_chooser_request_get_mime_types_filter() for more
+ * details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_FILTER,
+ g_param_spec_object("filter",
+ _("MIME types filter"),
+ _("The filter currently associated with the request"),
+ GTK_TYPE_FILE_FILTER,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:mime-types:
+ *
+ * A %NULL-terminated array of strings containing the list of MIME
+ * types the file chooser dialog should handle. See
+ * webkit_file_chooser_request_get_mime_types() for more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_MIME_TYPES,
+ g_param_spec_boxed("mime-types",
+ _("MIME types"),
+ _("The list of MIME types associated with the request"),
+ G_TYPE_STRV,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:select-multiple:
+ *
+ * Whether the file chooser should allow selecting multiple
+ * files. See
+ * webkit_file_chooser_request_get_select_multiple() for
+ * more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_SELECT_MULTIPLE,
+ g_param_spec_boolean("select-multiple",
+ _("Select multiple files"),
+ _("Whether the file chooser should allow selecting multiple files"),
+ FALSE,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:selected-files:
+ *
+ * A %NULL-terminated array of strings containing the list of
+ * selected files associated to the current request. See
+ * webkit_file_chooser_request_get_selected_files() for more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_SELECTED_FILES,
+ g_param_spec_boxed("selected-files",
+ _("Selected files"),
+ _("The list of selected files associated with the request"),
+ G_TYPE_STRV,
+ WEBKIT_PARAM_READABLE));
+}
+
+WebKitFileChooserRequest* webkitFileChooserRequestCreate(WKOpenPanelParametersRef wkParameters, WKOpenPanelResultListenerRef wkListener)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(g_object_new(WEBKIT_TYPE_FILE_CHOOSER_REQUEST, NULL));
+ request->priv->wkParameters = wkParameters;
+ request->priv->wkListener = wkListener;
+ return request;
+}
+
+/**
+ * webkit_file_chooser_request_get_mime_types:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the list of MIME types the file chooser dialog should handle,
+ * in the format specified in RFC 2046 for "media types". Its contents
+ * depend on the value of the 'accept' attribute for HTML input
+ * elements. This function should normally be called before presenting
+ * the file chooser dialog to the user, to decide whether to allow the
+ * user to select multiple files at once or only one.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings if a list of accepted MIME types
+ * is defined or %NULL otherwise, meaning that any MIME type should be
+ * accepted. This array and its contents are owned by WebKitGTK+ and
+ * should not be modified or freed.
+ */
+const gchar* const* webkit_file_chooser_request_get_mime_types(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->mimeTypes)
+ return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata);
+
+ WKRetainPtr<WKArrayRef> wkMimeTypes(AdoptWK, WKOpenPanelParametersCopyAcceptedMIMETypes(request->priv->wkParameters.get()));
+ size_t numOfMimeTypes = WKArrayGetSize(wkMimeTypes.get());
+ if (!numOfMimeTypes)
+ return 0;
+
+ request->priv->mimeTypes = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ for (size_t i = 0; i < numOfMimeTypes; ++i) {
+ WKStringRef wkMimeType = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkMimeTypes.get(), i));
+ String mimeTypeString = toImpl(wkMimeType)->string();
+ if (mimeTypeString.isEmpty())
+ continue;
+ g_ptr_array_add(request->priv->mimeTypes.get(), g_strdup(mimeTypeString.utf8().data()));
+ }
+ g_ptr_array_add(request->priv->mimeTypes.get(), 0);
+
+ return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata);
+}
+
+/**
+ * webkit_file_chooser_request_get_mime_types_filter:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the filter currently associated with the request, ready to be
+ * used by #GtkFileChooser. This function should normally be called
+ * before presenting the file chooser dialog to the user, to decide
+ * whether to apply a filter so the user would not be allowed to
+ * select files with other MIME types.
+ *
+ * See webkit_file_chooser_request_get_mime_types() if you are
+ * interested in getting the list of accepted MIME types.
+ *
+ * Returns: (transfer none): a #GtkFileFilter if a list of accepted
+ * MIME types is defined or %NULL otherwise. The returned object is
+ * owned by WebKitGTK+ should not be modified or freed.
+ */
+GtkFileFilter* webkit_file_chooser_request_get_mime_types_filter(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->filter)
+ return request->priv->filter.get();
+
+ WKRetainPtr<WKArrayRef> wkMimeTypes(AdoptWK, WKOpenPanelParametersCopyAcceptedMIMETypes(request->priv->wkParameters.get()));
+ size_t numOfMimeTypes = WKArrayGetSize(wkMimeTypes.get());
+ if (!numOfMimeTypes)
+ return 0;
+
+ // Do not use adoptGRef here, since we want to sink the floating
+ // reference for the new instance of GtkFileFilter, so we make
+ // sure we keep the ownership during the lifetime of the request.
+ request->priv->filter = gtk_file_filter_new();
+ for (size_t i = 0; i < numOfMimeTypes; ++i) {
+ WKStringRef wkMimeType = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkMimeTypes.get(), i));
+ String mimeTypeString = toImpl(wkMimeType)->string();
+ if (mimeTypeString.isEmpty())
+ continue;
+ gtk_file_filter_add_mime_type(request->priv->filter.get(), mimeTypeString.utf8().data());
+ }
+
+ return request->priv->filter.get();
+}
+
+/**
+ * webkit_file_chooser_request_get_select_multiple:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Determine whether the file chooser associated to this
+ * #WebKitFileChooserRequest should allow selecting multiple files,
+ * which depends on the HTML input element having a 'multiple'
+ * attribute defined.
+ *
+ * Returns: %TRUE if the file chooser should allow selecting multiple files or %FALSE otherwise.
+ */
+gboolean webkit_file_chooser_request_get_select_multiple(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), FALSE);
+ return WKOpenPanelParametersGetAllowsMultipleFiles(request->priv->wkParameters.get());
+}
+
+/**
+ * webkit_file_chooser_request_select_files:
+ * @request: a #WebKitFileChooserRequest
+ * @files: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings, containing paths to local files.
+ *
+ * Ask WebKit to select local files for upload and complete the
+ * request.
+ */
+void webkit_file_chooser_request_select_files(WebKitFileChooserRequest* request, const gchar* const* files)
+{
+ g_return_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request));
+ g_return_if_fail(files);
+
+ GRefPtr<GPtrArray> selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ WKRetainPtr<WKMutableArrayRef> wkChosenFiles(AdoptWK, WKMutableArrayCreate());
+ for (int i = 0; files[i]; i++) {
+ GRefPtr<GFile> filename = adoptGRef(g_file_new_for_path(files[i]));
+
+ // Make sure the file path is presented as an URI (escaped
+ // string, with the 'file://' prefix) to WebCore otherwise the
+ // FileChooser won't actually choose it.
+ GOwnPtr<char> uri(g_file_get_uri(filename.get()));
+ WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKURLCreateWithUTF8CString(uri.get()));
+ WKArrayAppendItem(wkChosenFiles.get(), wkURL.get());
+
+ // Do not use the URI here because this won't reach WebCore.
+ g_ptr_array_add(selectedFiles.get(), g_strdup(files[i]));
+ }
+ g_ptr_array_add(selectedFiles.get(), 0);
+
+ // Select the files in WebCore and update local private attributes.
+ WKOpenPanelResultListenerChooseFiles(request->priv->wkListener.get(), wkChosenFiles.get());
+ request->priv->selectedFiles = selectedFiles;
+ request->priv->handledRequest = true;
+}
+
+/**
+ * webkit_file_chooser_request_get_selected_files:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the list of selected files currently associated to the
+ * request. Initially, the return value of this method contains any
+ * files selected in previous file chooser requests for this HTML
+ * input element. Once webkit_file_chooser_request_select_files, the
+ * value will reflect whatever files are given.
+ *
+ * This function should normally be called only before presenting the
+ * file chooser dialog to the user, to decide whether to perform some
+ * extra action, like pre-selecting the files from a previous request.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings if there are selected files
+ * associated with the request or %NULL otherwise. This array and its
+ * contents are owned by WebKitGTK+ and should not be modified or
+ * freed.
+ */
+const gchar* const* webkit_file_chooser_request_get_selected_files(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->selectedFiles)
+ return reinterpret_cast<gchar**>(request->priv->selectedFiles->pdata);
+
+ const Vector<String> selectedFileNames = toImpl(request->priv->wkParameters.get())->selectedFileNames();
+ size_t numOfFiles = selectedFileNames.size();
+ if (!numOfFiles)
+ return 0;
+
+ request->priv->selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ for (size_t i = 0; i < numOfFiles; ++i) {
+ if (selectedFileNames[i].isEmpty())
+ continue;
+ CString filename = fileSystemRepresentation(selectedFileNames[i]);
+ g_ptr_array_add(request->priv->selectedFiles.get(), g_strdup(filename.data()));
+ }
+ g_ptr_array_add(request->priv->selectedFiles.get(), 0);
+
+ return reinterpret_cast<gchar**>(request->priv->selectedFiles->pdata);
+}
+
+/**
+ * webkit_file_chooser_request_cancel:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Ask WebKit to cancel the request. It's important to do this in case
+ * no selection has been made in the client, otherwise the request
+ * won't be properly completed and the browser will keep the request
+ * pending forever, which might cause the browser to hang.
+ */
+void webkit_file_chooser_request_cancel(WebKitFileChooserRequest* request)
+{
+ g_return_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request));
+ WKOpenPanelResultListenerCancel(request->priv->wkListener.get());
+ request->priv->handledRequest = true;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h
new file mode 100644
index 000000000..88eec9966
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h
@@ -0,0 +1,78 @@
+/*
+ * 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 WebKitFileChooserRequest_h
+#define WebKitFileChooserRequest_h
+
+#include <gtk/gtk.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_FILE_CHOOSER_REQUEST (webkit_file_chooser_request_get_type())
+#define WEBKIT_FILE_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequest))
+#define WEBKIT_FILE_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestClass))
+#define WEBKIT_IS_FILE_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_FILE_CHOOSER_REQUEST))
+#define WEBKIT_IS_FILE_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_FILE_CHOOSER_REQUEST))
+#define WEBKIT_FILE_CHOOSER_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestClass))
+
+typedef struct _WebKitFileChooserRequest WebKitFileChooserRequest;
+typedef struct _WebKitFileChooserRequestClass WebKitFileChooserRequestClass;
+typedef struct _WebKitFileChooserRequestPrivate WebKitFileChooserRequestPrivate;
+
+struct _WebKitFileChooserRequest {
+ GObject parent;
+
+ /*< private >*/
+ WebKitFileChooserRequestPrivate *priv;
+};
+
+struct _WebKitFileChooserRequestClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_file_chooser_request_get_type (void);
+
+WEBKIT_API const gchar * const *
+webkit_file_chooser_request_get_mime_types (WebKitFileChooserRequest *request);
+
+WEBKIT_API GtkFileFilter *
+webkit_file_chooser_request_get_mime_types_filter (WebKitFileChooserRequest *request);
+
+WEBKIT_API gboolean
+webkit_file_chooser_request_get_select_multiple (WebKitFileChooserRequest *request);
+
+WEBKIT_API void
+webkit_file_chooser_request_select_files (WebKitFileChooserRequest *request,
+ const gchar * const *files);
+
+WEBKIT_API const gchar * const *
+webkit_file_chooser_request_get_selected_files (WebKitFileChooserRequest *request);
+
+WEBKIT_API void
+webkit_file_chooser_request_cancel (WebKitFileChooserRequest *request);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h
new file mode 100644
index 000000000..af7224a96
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitFileChooserRequestPrivate_h
+#define WebKitFileChooserRequestPrivate_h
+
+#include "WebKitFileChooserRequest.h"
+#include "WebKitPrivate.h"
+
+WebKitFileChooserRequest* webkitFileChooserRequestCreate(WKOpenPanelParametersRef, WKOpenPanelResultListenerRef);
+
+#endif // WebKitFileChooserRequestPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp
new file mode 100644
index 000000000..75b51e25d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "WebKitFullscreenClient.h"
+
+#include "WebKitPrivate.h"
+#include "WebKitWebViewPrivate.h"
+
+using namespace WebKit;
+
+static bool willEnterFullScreen(const void* clientInfo)
+{
+ return webkitWebViewEnterFullScreen(WEBKIT_WEB_VIEW(clientInfo));
+}
+
+static bool willExitFullScreen(const void* clientInfo)
+{
+ return webkitWebViewLeaveFullScreen(WEBKIT_WEB_VIEW(clientInfo));
+}
+
+void attachFullScreenClientToView(WebKitWebView* webView)
+{
+ WKFullScreenClientGtk wkFullScreenClient = {
+ kWKFullScreenClientGtkCurrentVersion,
+ webView, // clientInfo
+ willEnterFullScreen,
+ willExitFullScreen
+ };
+ WKViewSetFullScreenClientGtk(toAPI(WEBKIT_WEB_VIEW_BASE(webView)), &wkFullScreenClient);
+}
+
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h
new file mode 100644
index 000000000..187c067af
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitFullscreenClient_h
+#define WebKitFullscreenClient_h
+
+#include "WebKitWebView.h"
+
+void attachFullScreenClientToView(WebKitWebView*);
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp
new file mode 100644
index 000000000..84ad04d03
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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 "WebKitJavascriptResult.h"
+
+#include "WebKitJavascriptResultPrivate.h"
+#include <wtf/gobject/GRefPtr.h>
+
+struct _WebKitJavascriptResult {
+ _WebKitJavascriptResult(WebKitWebView* view, WKSerializedScriptValueRef wkSerializedScriptValue)
+ : webView(view)
+ , referenceCount(1)
+ {
+ value = WKSerializedScriptValueDeserialize(wkSerializedScriptValue, webkit_web_view_get_javascript_global_context(view), 0);
+ }
+
+ GRefPtr<WebKitWebView> webView;
+ JSValueRef value;
+
+ int referenceCount;
+};
+
+G_DEFINE_BOXED_TYPE(WebKitJavascriptResult, webkit_javascript_result, webkit_javascript_result_ref, webkit_javascript_result_unref)
+
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WKSerializedScriptValueRef wkSerializedScriptValue)
+{
+ WebKitJavascriptResult* result = g_slice_new(WebKitJavascriptResult);
+ new (result) WebKitJavascriptResult(webView, wkSerializedScriptValue);
+ return result;
+}
+
+/**
+ * webkit_javascript_result_ref:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Atomically increments the reference count of @js_result by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #WebKitJavascriptResult
+ */
+WebKitJavascriptResult* webkit_javascript_result_ref(WebKitJavascriptResult* javascriptResult)
+{
+ g_atomic_int_inc(&javascriptResult->referenceCount);
+ return javascriptResult;
+}
+
+/**
+ * webkit_javascript_result_unref:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Atomically decrements the reference count of @js_result by one. If the
+ * reference count drops to 0, all memory allocated by the #WebKitJavascriptResult is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ */
+void webkit_javascript_result_unref(WebKitJavascriptResult* javascriptResult)
+{
+ if (g_atomic_int_dec_and_test(&javascriptResult->referenceCount)) {
+ javascriptResult->~WebKitJavascriptResult();
+ g_slice_free(WebKitJavascriptResult, javascriptResult);
+ }
+}
+
+/**
+ * webkit_javascript_result_get_global_context:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Get the global Javascript context that should be used with the
+ * <function>JSValueRef</function> returned by webkit_javascript_result_get_value().
+ *
+ * Returns: the <function>JSGlobalContextRef</function> for the #WebKitJavascriptResult
+ */
+JSGlobalContextRef webkit_javascript_result_get_global_context(WebKitJavascriptResult* javascriptResult)
+{
+ return webkit_web_view_get_javascript_global_context(javascriptResult->webView.get());
+}
+
+/**
+ * webkit_javascript_result_get_value:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Get the value of @js_result. You should use the <function>JSGlobalContextRef</function>
+ * returned by webkit_javascript_result_get_global_context() to use the <function>JSValueRef</function>.
+ *
+ * Returns: the <function>JSValueRef</function> of the #WebKitJavascriptResult
+ */
+JSValueRef webkit_javascript_result_get_value(WebKitJavascriptResult* javascriptResult)
+{
+ return javascriptResult->value;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h
new file mode 100644
index 000000000..5a9f7389f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h
@@ -0,0 +1,55 @@
+/*
+ * 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 WebKitJavascriptResult_h
+#define WebKitJavascriptResult_h
+
+#include <JavaScriptCore/JSBase.h>
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_JAVASCRIPT_RESULT (webkit_javascript_result_get_type())
+
+typedef struct _WebKitJavascriptResult WebKitJavascriptResult;
+
+
+WEBKIT_API GType
+webkit_javascript_result_get_type (void);
+
+WEBKIT_API WebKitJavascriptResult *
+webkit_javascript_result_ref (WebKitJavascriptResult *js_result);
+
+WEBKIT_API void
+webkit_javascript_result_unref (WebKitJavascriptResult *js_result);
+
+WEBKIT_API JSGlobalContextRef
+webkit_javascript_result_get_global_context (WebKitJavascriptResult *js_result);
+
+WEBKIT_API JSValueRef
+webkit_javascript_result_get_value (WebKitJavascriptResult *js_result);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h
new file mode 100644
index 000000000..840ead058
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h
@@ -0,0 +1,29 @@
+/*
+ * 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 WebKitJavascriptResultPrivate_h
+#define WebKitJavascriptResultPrivate_h
+
+#include "WebKitJavascriptResult.h"
+#include "WebKitPrivate.h"
+#include "WebKitWebView.h"
+
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WKSerializedScriptValueRef);
+
+#endif // WebKitJavascriptResultPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp
index d79d40149..7da0b197a 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp
@@ -28,7 +28,9 @@
#include <WebCore/GtkUtilities.h>
#include <WebCore/NotImplemented.h>
#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
#ifdef HAVE_GTK_UNIX_PRINTING
#include <gtk/gtkunixprint.h>
@@ -46,6 +48,7 @@ enum {
enum {
FINISHED,
+ FAILED,
LAST_SIGNAL
};
@@ -193,6 +196,24 @@ static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOp
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * WebKitPrintOperation::failed:
+ * @print_operation: the #WebKitPrintOperation on which the signal was emitted
+ * @error: the #GError that was triggered
+ *
+ * Emitted when an error occurs while printing. The given @error, of the domain
+ * %WEBKIT_PRINT_ERROR, contains further details of the failure.
+ * The #WebKitPrintOperation::finished signal is emitted after this one.
+ */
+ signals[FAILED] =
+ g_signal_new("failed",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
g_type_class_add_private(printOperationClass, sizeof(WebKitPrintOperationPrivate));
}
@@ -237,11 +258,19 @@ static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOpe
}
#endif
-static void drawPagesForPrintingCompleted(WKErrorRef, void* context)
+static void drawPagesForPrintingCompleted(WKErrorRef wkPrintError, WKErrorRef, void* context)
{
GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context));
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
page->endPrinting();
+
+ const WebCore::ResourceError& resourceError = toImpl(wkPrintError)->platformError();
+ if (!resourceError.isNull()) {
+ GOwnPtr<GError> printError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
+ resourceError.errorCode(),
+ resourceError.localizedDescription().utf8().data()));
+ g_signal_emit(printOperation.get(), signals[FAILED], 0, printError.get());
+ }
g_signal_emit(printOperation.get(), signals[FINISHED], 0, NULL);
}
@@ -249,7 +278,7 @@ static void webkitPrintOperationPrintPagesForFrame(WebKitPrintOperation* printOp
{
PrintInfo printInfo(printSettings, pageSetup);
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
- page->drawPagesForPrinting(webFrame, printInfo, VoidCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted));
+ page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted));
}
WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation* printOperation, GtkWindow* parent, WebFrameProxy* webFrame)
@@ -368,7 +397,8 @@ void webkit_print_operation_set_page_setup(WebKitPrintOperation* printOperation,
* 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
- * signal is emitted when the operation finishes.
+ * signal is emitted when the operation finishes. If an error occurs while printing, the signal
+ * #WebKitPrintOperation::failed is emitted before #WebKitPrintOperation::finished.
* 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.
* You can get the updated print settings and page setup by calling
@@ -395,7 +425,8 @@ WebKitPrintOperationResponse webkit_print_operation_run_dialog(WebKitPrintOperat
* 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
- * operation finishes.
+ * operation finishes. If an error occurs while printing the signal
+ * #WebKitPrintOperation::failed is emitted before #WebKitPrintOperation::finished.
*/
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 e785c3638..4b7e9ad49 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
@@ -29,7 +29,9 @@
#include <WebKit2/WKAPICast.h>
#include <WebKit2/WKDownload.h>
#include <WebKit2/WKFindOptions.h>
+#include <WebKit2/WKFullScreenClientGtk.h>
#include <WebKit2/WKRetainPtr.h>
+#include <WebKit2/WKSerializedScriptValue.h>
#include <WebKit2/WKString.h>
#include <WebKit2/WebKit2.h>
#include <glib.h>
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
new file mode 100644
index 000000000..1cd8aaf7f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
@@ -0,0 +1,112 @@
+/*
+ * 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 "WebKitResourceLoadClient.h"
+
+#include "WebContext.h"
+#include "WebKitURIRequestPrivate.h"
+#include "WebKitURIResponsePrivate.h"
+#include "WebKitWebResourcePrivate.h"
+#include "WebKitWebViewBasePrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include "WebURLResponse.h"
+#include <WebKit2/WKString.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+static void didInitiateLoadForResource(WKPageRef, WKFrameRef wkFrame, uint64_t resourceIdentifier, WKURLRequestRef wkRequest, bool pageIsProvisionallyLoading, const void* clientInfo)
+{
+ GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(wkRequest)->resourceRequest()));
+ webkitWebViewResourceLoadStarted(WEBKIT_WEB_VIEW(clientInfo), wkFrame, resourceIdentifier, request.get(), pageIsProvisionallyLoading);
+}
+
+static void didSendRequestForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKURLRequestRef wkRequest, WKURLResponseRef wkRedirectResponse, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(wkRequest)->resourceRequest()));
+ GRefPtr<WebKitURIResponse> redirectResponse = wkRedirectResponse ? adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkRedirectResponse)->resourceResponse())) : 0;
+ webkitWebResourceSentRequest(resource.get(), request.get(), redirectResponse.get());
+}
+
+static void didReceiveResponseForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKURLResponseRef wkResponse, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkResponse)->resourceResponse()));
+ webkitWebResourceSetResponse(resource.get(), response.get());
+}
+
+static void didReceiveContentLengthForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, uint64_t contentLength, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ webkitWebResourceNotifyProgress(resource.get(), contentLength);
+}
+
+static void didFinishLoadForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewResourceLoadFinished(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ webkitWebResourceFinished(resource.get());
+}
+
+static void didFailLoadForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKErrorRef wkError, const void* clientInfo)
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(clientInfo);
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(webView, resourceIdentifier);
+ if (!resource)
+ return;
+
+ const ResourceError& resourceError = toImpl(wkError)->platformError();
+ GOwnPtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
+ resourceError.errorCode(),
+ resourceError.localizedDescription().utf8().data()));
+ webkitWebResourceFailed(resource.get(), webError.get());
+ webkitWebViewRemoveLoadingWebResource(webView, resourceIdentifier);
+}
+
+void attachResourceLoadClientToView(WebKitWebView* webView)
+{
+ WKPageResourceLoadClient wkResourceLoadClient = {
+ kWKPageResourceLoadClientCurrentVersion,
+ webView, // ClientInfo
+ didInitiateLoadForResource,
+ didSendRequestForResource,
+ didReceiveResponseForResource,
+ didReceiveContentLengthForResource,
+ didFinishLoadForResource,
+ didFailLoadForResource,
+ };
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKPageSetPageResourceLoadClient(wkPage, &wkResourceLoadClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h
new file mode 100644
index 000000000..0e6a3613c
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitResourceLoadClient_h
+#define WebKitResourceLoadClient_h
+
+#include "WebKitWebView.h"
+
+void attachResourceLoadClientToView(WebKitWebView*);
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
index b4b267d1b..8bec722b3 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
@@ -105,7 +105,8 @@ enum {
PROP_PRINT_BACKGROUNDS,
PROP_ENABLE_WEBAUDIO,
PROP_ENABLE_WEBGL,
- PROP_ZOOM_TEXT_ONLY
+ PROP_ZOOM_TEXT_ONLY,
+ PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD
};
static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
@@ -215,6 +216,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu
case PROP_ZOOM_TEXT_ONLY:
webkit_settings_set_zoom_text_only(settings, g_value_get_boolean(value));
break;
+ case PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD:
+ webkit_settings_set_javascript_can_access_clipboard(settings, g_value_get_boolean(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
break;
@@ -328,6 +332,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val
case PROP_ZOOM_TEXT_ONLY:
g_value_set_boolean(value, webkit_settings_get_zoom_text_only(settings));
break;
+ case PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD:
+ g_value_set_boolean(value, webkit_settings_get_javascript_can_access_clipboard(settings));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
break;
@@ -840,6 +847,21 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass)
FALSE,
readWriteConstructParamFlags));
+ /**
+ * WebKitSettings:javascript-can-access-clipboard:
+ *
+ * Whether JavaScript can access the clipboard. The default value is %FALSE. If
+ * set to %TRUE, document.execCommand() allows cut, copy and paste commands.
+ *
+ */
+ g_object_class_install_property(gObjectClass,
+ PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD,
+ g_param_spec_boolean("javascript-can-access-clipboard",
+ _("JavaScript can access clipboard"),
+ _("Whether JavaScript can access Clipboard"),
+ FALSE,
+ readWriteConstructParamFlags));
+
g_type_class_add_private(klass, sizeof(WebKitSettingsPrivate));
}
@@ -2133,3 +2155,41 @@ gboolean webkit_settings_get_zoom_text_only(WebKitSettings* settings)
return settings->priv->zoomTextOnly;
}
+/**
+ * webkit_settings_get_javascript_can_access_clipboard:
+ * @settings: a #WebKitSettings
+ *
+ * Get the #WebKitSettings:javascript-can-access-clipboard property.
+ *
+ * Returns: %TRUE If javascript-can-access-clipboard is enabled or %FALSE otherwise.
+ */
+gboolean webkit_settings_get_javascript_can_access_clipboard(WebKitSettings* settings)
+{
+ g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE);
+
+ return WKPreferencesGetJavaScriptCanAccessClipboard(settings->priv->preferences.get())
+ && WKPreferencesGetDOMPasteAllowed(settings->priv->preferences.get());
+}
+
+/**
+ * webkit_settings_set_javascript_can_access_clipboard:
+ * @settings: a #WebKitSettings
+ * @enabled: Value to be set
+ *
+ * Set the #WebKitSettings:javascript-can-access-clipboard property.
+ */
+void webkit_settings_set_javascript_can_access_clipboard(WebKitSettings* settings, gboolean enabled)
+{
+ g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
+
+ WebKitSettingsPrivate* priv = settings->priv;
+ bool currentValue = WKPreferencesGetJavaScriptCanAccessClipboard(priv->preferences.get())
+ && WKPreferencesGetDOMPasteAllowed(priv->preferences.get());
+ if (currentValue == enabled)
+ return;
+
+ WKPreferencesSetJavaScriptCanAccessClipboard(priv->preferences.get(), enabled);
+ WKPreferencesSetDOMPasteAllowed(priv->preferences.get(), enabled);
+
+ g_object_notify(G_OBJECT(settings), "javascript-can-access-clipboard");
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
index 25a78aca3..57bf3f17d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
@@ -314,6 +314,13 @@ webkit_settings_set_zoom_text_only (WebKitSettings *
WEBKIT_API gboolean
webkit_settings_get_zoom_text_only (WebKitSettings *settings);
+WEBKIT_API gboolean
+webkit_settings_get_javascript_can_access_clipboard (WebKitSettings *settings);
+
+WEBKIT_API void
+webkit_settings_set_javascript_can_access_clipboard (WebKitSettings *settings,
+ gboolean enabled);
+
G_END_DECLS
#endif /* WebKitSettings_h */
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
index 6f0e11c82..9f78c9cbf 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
@@ -20,12 +20,14 @@
#include "config.h"
#include "WebKitUIClient.h"
+#include "WebKitFileChooserRequestPrivate.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebPageProxy.h"
#include <WebCore/GtkUtilities.h>
+#include <wtf/gobject/GRefPtr.h>
using namespace WebKit;
@@ -136,6 +138,12 @@ static void printFrame(WKPageRef page, WKFrameRef frame, const void*)
webkitWebViewPrintFrame(WEBKIT_WEB_VIEW(toImpl(page)->viewWidget()), frame);
}
+static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void *clientInfo)
+{
+ GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(parameters, listener));
+ webkitWebViewRunFileChooserRequest(WEBKIT_WEB_VIEW(clientInfo), request.get());
+}
+
void attachUIClientToView(WebKitWebView* webView)
{
WKPageUIClient wkUIClient = {
@@ -169,7 +177,7 @@ void attachUIClientToView(WebKitWebView* webView)
0, // didDraw
0, // pageDidScroll
0, // exceededDatabaseQuota
- 0, // runOpenPanel
+ runOpenPanel,
0, // decidePolicyForGeolocationPermissionRequest
0, // headerHeight
0, // footerHeight
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
index 360b0a627..0b68c086d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
@@ -21,6 +21,7 @@
#include "WebKitWebContext.h"
#include "WebContext.h"
+#include "WebKitCookieManagerPrivate.h"
#include "WebKitDownloadClient.h"
#include "WebKitDownloadPrivate.h"
#include "WebKitPrivate.h"
@@ -39,6 +40,8 @@ enum {
struct _WebKitWebContextPrivate {
WKRetainPtr<WKContextRef> context;
+
+ GRefPtr<WebKitCookieManager> cookieManager;
};
static guint signals[LAST_SIGNAL] = { 0, };
@@ -84,12 +87,11 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
static gpointer createDefaultWebContext(gpointer)
{
- WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL));
+ static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL)));
webContext->priv->context = WKContextGetSharedProcessContext();
WKContextSetCacheModel(webContext->priv->context.get(), kWKCacheModelPrimaryWebBrowser);
- attachDownloadClientToContext(webContext);
-
- return webContext;
+ attachDownloadClientToContext(webContext.get());
+ return webContext.get();
}
/**
@@ -215,6 +217,25 @@ WebKitDownload* webkit_web_context_download_uri(WebKitWebContext* context, const
return download;
}
+/**
+ * webkit_web_context_get_cookie_manager:
+ * @context: a #WebKitWebContext
+ *
+ * Get the #WebKitCookieManager of @context.
+ *
+ * Returns: (transfer none): the #WebKitCookieManager of @context.
+ */
+WebKitCookieManager* webkit_web_context_get_cookie_manager(WebKitWebContext* context)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0);
+
+ WebKitWebContextPrivate* priv = context->priv;
+ if (!priv->cookieManager)
+ priv->cookieManager = adoptGRef(webkitCookieManagerCreate(WKContextGetCookieManager(priv->context.get())));
+
+ return priv->cookieManager.get();
+}
+
WebKitDownload* webkitWebContextGetOrCreateDownload(WKDownloadRef wkDownload)
{
GRefPtr<WebKitDownload> download = downloadsMap().get(wkDownload);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
index b88bed0da..45b6e6c1d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
@@ -25,6 +25,7 @@
#define WebKitWebContext_h
#include <glib-object.h>
+#include <webkit2/WebKitCookieManager.h>
#include <webkit2/WebKitDefines.h>
#include <webkit2/WebKitDownload.h>
@@ -79,20 +80,23 @@ struct _WebKitWebContextClass {
};
WEBKIT_API GType
-webkit_web_context_get_type (void);
+webkit_web_context_get_type (void);
WEBKIT_API WebKitWebContext *
-webkit_web_context_get_default (void);
+webkit_web_context_get_default (void);
WEBKIT_API void
-webkit_web_context_set_cache_model (WebKitWebContext *context,
- WebKitCacheModel cache_model);
+webkit_web_context_set_cache_model (WebKitWebContext *context,
+ WebKitCacheModel cache_model);
WEBKIT_API WebKitCacheModel
-webkit_web_context_get_cache_model (WebKitWebContext *context);
+webkit_web_context_get_cache_model (WebKitWebContext *context);
WEBKIT_API WebKitDownload *
-webkit_web_context_download_uri (WebKitWebContext *context,
- const gchar *uri);
+webkit_web_context_download_uri (WebKitWebContext *context,
+ const gchar *uri);
+
+WEBKIT_API WebKitCookieManager *
+webkit_web_context_get_cookie_manager (WebKitWebContext *context);
G_END_DECLS
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
new file mode 100644
index 000000000..6bd51fa08
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
@@ -0,0 +1,363 @@
+/*
+ * 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 "WebKitWebResource.h"
+
+#include "WebKitMarshal.h"
+#include "WebKitURIRequest.h"
+#include "WebKitWebResourcePrivate.h"
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+enum {
+ SENT_REQUEST,
+ RECEIVED_DATA,
+ FINISHED,
+ FAILED,
+
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+
+ PROP_URI,
+ PROP_RESPONSE
+};
+
+
+struct _WebKitWebResourcePrivate {
+ WKRetainPtr<WKFrameRef> wkFrame;
+ CString uri;
+ GRefPtr<WebKitURIResponse> response;
+ bool isMainResource;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE(WebKitWebResource, webkit_web_resource, G_TYPE_OBJECT)
+
+static void webkitWebResourceFinalize(GObject* object)
+{
+ WEBKIT_WEB_RESOURCE(object)->priv->~WebKitWebResourcePrivate();
+ G_OBJECT_CLASS(webkit_web_resource_parent_class)->finalize(object);
+}
+
+static void webkitWebResourceGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitWebResource* resource = WEBKIT_WEB_RESOURCE(object);
+
+ switch (propId) {
+ case PROP_URI:
+ g_value_set_string(value, webkit_web_resource_get_uri(resource));
+ break;
+ case PROP_RESPONSE:
+ g_value_set_object(value, webkit_web_resource_get_response(resource));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ }
+}
+
+static void webkit_web_resource_init(WebKitWebResource* resource)
+{
+ WebKitWebResourcePrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(resource, WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourcePrivate);
+ resource->priv = priv;
+ new (priv) WebKitWebResourcePrivate();
+}
+
+static void webkit_web_resource_class_init(WebKitWebResourceClass* resourceClass)
+{
+ GObjectClass* objectClass = G_OBJECT_CLASS(resourceClass);
+ objectClass->get_property = webkitWebResourceGetProperty;
+ objectClass->finalize = webkitWebResourceFinalize;
+
+ /**
+ * WebKitWebResource:uri:
+ *
+ * The current active URI of the #WebKitWebResource.
+ * See webkit_web_resource_get_uri() for more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_URI,
+ g_param_spec_string("uri",
+ _("URI"),
+ _("The current active URI of the result"),
+ 0,
+ WEBKIT_PARAM_READABLE));
+
+ /**
+ * WebKitWebResource:response:
+ *
+ * The #WebKitURIResponse associated with this resource.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_RESPONSE,
+ g_param_spec_object("response",
+ _("Response"),
+ _("The response of the resource"),
+ WEBKIT_TYPE_URI_RESPONSE,
+ WEBKIT_PARAM_READABLE));
+
+ /**
+ * WebKitWebResource::sent-request:
+ * @resource: the #WebKitWebResource
+ * @request: a #WebKitURIRequest
+ * @redirected_response: a #WebKitURIResponse, or %NULL
+ *
+ * This signal is emitted when @request has been sent to the
+ * server. In case of a server redirection this signal is
+ * emitted again with the @request argument containing the new
+ * request sent to the server due to the redirection and the
+ * @redirected_response parameter containing the response
+ * received by the server for the initial request.
+ */
+ signals[SENT_REQUEST] =
+ g_signal_new("sent-request",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ webkit_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ WEBKIT_TYPE_URI_REQUEST,
+ WEBKIT_TYPE_URI_RESPONSE);
+
+ /**
+ * WebKitWebResource::received-data:
+ * @resource: the #WebKitWebResource
+ * @data_length: the length of data received in bytes
+ *
+ * This signal is emitted after response is received,
+ * every time new data has been received. It's
+ * useful to know the progress of the resource load operation.
+ */
+ signals[RECEIVED_DATA] =
+ g_signal_new("received-data",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ webkit_marshal_VOID__UINT64,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT64);
+
+ /**
+ * WebKitWebResource::finished:
+ * @resource: the #WebKitWebResource
+ *
+ * This signal is emitted when the resource load finishes successfully
+ * or due to an error. In case of errors #WebKitWebResource::failed signal
+ * is emitted before this one.
+ */
+ signals[FINISHED] =
+ g_signal_new("finished",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * WebKitWebResource::failed:
+ * @resource: the #WebKitWebResource
+ * @error: the #GError that was triggered
+ *
+ * This signal is emitted when an error occurs during the resource
+ * load operation.
+ */
+ signals[FAILED] =
+ g_signal_new("failed",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ g_type_class_add_private(resourceClass, sizeof(WebKitWebResourcePrivate));
+}
+
+static void webkitWebResourceUpdateURI(WebKitWebResource* resource, const CString& requestURI)
+{
+ if (resource->priv->uri == requestURI)
+ return;
+
+ resource->priv->uri = requestURI;
+ g_object_notify(G_OBJECT(resource), "uri");
+}
+
+WebKitWebResource* webkitWebResourceCreate(WKFrameRef wkFrame, WebKitURIRequest* request, bool isMainResource)
+{
+ ASSERT(wkFrame);
+ WebKitWebResource* resource = WEBKIT_WEB_RESOURCE(g_object_new(WEBKIT_TYPE_WEB_RESOURCE, NULL));
+ resource->priv->wkFrame = wkFrame;
+ resource->priv->uri = webkit_uri_request_get_uri(request);
+ resource->priv->isMainResource = isMainResource;
+ return resource;
+}
+
+void webkitWebResourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+{
+ webkitWebResourceUpdateURI(resource, webkit_uri_request_get_uri(request));
+ g_signal_emit(resource, signals[SENT_REQUEST], 0, request, redirectResponse);
+}
+
+void webkitWebResourceSetResponse(WebKitWebResource* resource, WebKitURIResponse* response)
+{
+ resource->priv->response = response;
+ g_object_notify(G_OBJECT(resource), "response");
+}
+
+void webkitWebResourceNotifyProgress(WebKitWebResource* resource, guint64 bytesReceived)
+{
+ g_signal_emit(resource, signals[RECEIVED_DATA], 0, bytesReceived);
+}
+
+void webkitWebResourceFinished(WebKitWebResource* resource)
+{
+ g_signal_emit(resource, signals[FINISHED], 0, NULL);
+}
+
+void webkitWebResourceFailed(WebKitWebResource* resource, GError* error)
+{
+ g_signal_emit(resource, signals[FAILED], 0, error);
+ g_signal_emit(resource, signals[FINISHED], 0, NULL);
+}
+
+/**
+ * webkit_web_resource_get_uri:
+ * @resource: a #WebKitWebResource
+ *
+ * Returns the current active URI of @web_view. The active URI might change during
+ * a load operation:
+ *
+ * <orderedlist>
+ * <listitem><para>
+ * When the resource load starts, the active URI is the requested URI
+ * </para></listitem>
+ * <listitem><para>
+ * When the initial request is sent to the server, #WebKitWebResource::sent-request
+ * signal is emitted without a redirected response, the active URI is the URI of
+ * the request sent to the server.
+ * </para></listitem>
+ * <listitem><para>
+ * In case of a server redirection, #WebKitWebResource::sent-request signal
+ * is emitted again with a redirected response, the active URI is the URI the request
+ * was redirected to.
+ * </para></listitem>
+ * <listitem><para>
+ * When the response is received from the server, the active URI is the final
+ * one and it will not change again.
+ * </para></listitem>
+ * </orderedlist>
+ *
+ * You can monitor the active URI by connecting to the notify::uri
+ * signal of @resource.
+ *
+ * Returns: the current active URI of @resource
+ */
+const char* webkit_web_resource_get_uri(WebKitWebResource* resource)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(resource), 0);
+
+ return resource->priv->uri.data();
+}
+
+/**
+ * webkit_web_resource_get_response:
+ * @resource: a #WebKitWebResource
+ *
+ * Retrieves the #WebKitURIResponse of the resource load operation.
+ * This method returns %NULL if called before the response
+ * is received from the server. You can connect to notify::response
+ * signal to be notified when the response is received.
+ *
+ * Returns: (transfer none): the #WebKitURIResponse, or %NULL if
+ * the response hasn't been received yet.
+ */
+WebKitURIResponse* webkit_web_resource_get_response(WebKitWebResource* resource)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(resource), 0);
+
+ return resource->priv->response.get();
+}
+
+static void resourceDataCallback(WKDataRef data, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ g_simple_async_result_set_op_res_gpointer(result.get(), const_cast<OpaqueWKData*>(data), 0);
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_web_resource_get_data:
+ * @resource: a #WebKitWebResource
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously get the raw data for @resource.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_web_resource_get_data_finish() to get the result of the operation.
+ */
+void webkit_web_resource_get_data(WebKitWebResource* resource, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_RESOURCE(resource));
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(resource), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_resource_get_data));
+ if (resource->priv->isMainResource)
+ WKFrameGetMainResourceData(resource->priv->wkFrame.get(), resourceDataCallback, result);
+ else {
+ WKRetainPtr<WKURLRef> url(AdoptWK, WKURLCreateWithUTF8CString(resource->priv->uri.data()));
+ WKFrameGetResourceData(resource->priv->wkFrame.get(), url.get(), resourceDataCallback, result);
+ }
+}
+
+/**
+ * webkit_web_resource_get_data_finish:
+ * @resource: a #WebKitWebResource
+ * @result: a #GAsyncResult
+ * @length: (out): return location for the length of the resource data
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_resource_get_data().
+ *
+ * Returns: (transfer full): a string with the data of @resource, or %NULL in case
+ * of error. if @length is not %NULL, the size of the data will be assigned to it.
+ */
+guchar* webkit_web_resource_get_data_finish(WebKitWebResource* resource, GAsyncResult* result, gsize* length, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(resource), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simple = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simple) == webkit_web_resource_get_data);
+
+ if (g_simple_async_result_propagate_error(simple, error))
+ return 0;
+
+ WKDataRef wkData = static_cast<WKDataRef>(g_simple_async_result_get_op_res_gpointer(simple));
+ if (length)
+ *length = WKDataGetSize(wkData);
+ return static_cast<guchar*>(g_memdup(WKDataGetBytes(wkData), WKDataGetSize(wkData)));
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
new file mode 100644
index 000000000..34af76e2b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
@@ -0,0 +1,77 @@
+/*
+ * 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 WebKitWebResource_h
+#define WebKitWebResource_h
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitURIResponse.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_WEB_RESOURCE (webkit_web_resource_get_type())
+#define WEBKIT_WEB_RESOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResource))
+#define WEBKIT_IS_WEB_RESOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEB_RESOURCE))
+#define WEBKIT_WEB_RESOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourceClass))
+#define WEBKIT_IS_WEB_RESOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_RESOURCE))
+#define WEBKIT_WEB_RESOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourceClass))
+
+typedef struct _WebKitWebResource WebKitWebResource;
+typedef struct _WebKitWebResourceClass WebKitWebResourceClass;
+typedef struct _WebKitWebResourcePrivate WebKitWebResourcePrivate;
+
+struct _WebKitWebResource {
+ GObject parent;
+
+ WebKitWebResourcePrivate *priv;
+};
+
+struct _WebKitWebResourceClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_web_resource_get_type (void);
+
+WEBKIT_API const gchar *
+webkit_web_resource_get_uri (WebKitWebResource *resource);
+
+WEBKIT_API WebKitURIResponse *
+webkit_web_resource_get_response (WebKitWebResource *resource);
+
+WEBKIT_API void
+webkit_web_resource_get_data (WebKitWebResource *resource,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API guchar *
+webkit_web_resource_get_data_finish (WebKitWebResource *resource,
+ GAsyncResult *result,
+ gsize *length,
+ GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
new file mode 100644
index 000000000..5011ae4dd
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
@@ -0,0 +1,34 @@
+/*
+ * 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 WebKitWebResourcePrivate_h
+#define WebKitWebResourcePrivate_h
+
+#include "WebKitPrivate.h"
+#include "WebKitWebResource.h"
+
+WebKitWebResource* webkitWebResourceCreate(WKFrameRef, WebKitURIRequest*, bool isMainResource);
+void webkitWebResourceSentRequest(WebKitWebResource*, WebKitURIRequest*, WebKitURIResponse*);
+void webkitWebResourceSetResponse(WebKitWebResource*, WebKitURIResponse*);
+void webkitWebResourceNotifyProgress(WebKitWebResource*, guint64 bytesReceived);
+void webkitWebResourceFinished(WebKitWebResource*);
+void webkitWebResourceFailed(WebKitWebResource*, GError*);
+
+
+#endif // WebKitWebResourcePrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
index 4f17d4669..56b21df49 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
@@ -24,20 +24,25 @@
#include "WebKitBackForwardListPrivate.h"
#include "WebKitEnumTypes.h"
#include "WebKitError.h"
+#include "WebKitFullscreenClient.h"
#include "WebKitHitTestResultPrivate.h"
+#include "WebKitJavascriptResultPrivate.h"
#include "WebKitLoaderClient.h"
#include "WebKitMarshal.h"
#include "WebKitPolicyClient.h"
#include "WebKitPrintOperationPrivate.h"
#include "WebKitPrivate.h"
+#include "WebKitResourceLoadClient.h"
#include "WebKitScriptDialogPrivate.h"
#include "WebKitSettingsPrivate.h"
#include "WebKitUIClient.h"
#include "WebKitWebContextPrivate.h"
+#include "WebKitWebResourcePrivate.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebPageProxy.h"
+#include <JavaScriptCore/APICast.h>
#include <WebCore/DragIcon.h>
#include <WebCore/GtkUtilities.h>
#include <glib/gi18n-lib.h>
@@ -64,6 +69,13 @@ enum {
PRINT_REQUESTED,
+ RESOURCE_LOAD_STARTED,
+
+ ENTER_FULLSCREEN,
+ LEAVE_FULLSCREEN,
+
+ RUN_FILE_CHOOSER,
+
LAST_SIGNAL
};
@@ -84,6 +96,9 @@ typedef enum {
DidReplaceContent
} ReplaceContentStatus;
+typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap;
+typedef HashMap<String, GRefPtr<WebKitWebResource> > ResourcesMap;
+
struct _WebKitWebViewPrivate {
WebKitWebContext* context;
CString title;
@@ -100,6 +115,11 @@ struct _WebKitWebViewPrivate {
unsigned mouseTargetModifiers;
GRefPtr<WebKitFindController> findController;
+ JSGlobalContextRef javascriptGlobalContext;
+
+ GRefPtr<WebKitWebResource> mainResource;
+ LoadingResourcesMap loadingResourcesMap;
+ ResourcesMap subresourcesMap;
};
static guint signals[LAST_SIGNAL] = { 0, };
@@ -188,6 +208,49 @@ static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* set
g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
}
+static void fileChooserDialogResponseCallback(GtkDialog* dialog, gint responseID, WebKitFileChooserRequest* request)
+{
+ GRefPtr<WebKitFileChooserRequest> adoptedRequest = adoptGRef(request);
+ if (responseID == GTK_RESPONSE_ACCEPT) {
+ GOwnPtr<GSList> filesList(gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)));
+ GRefPtr<GPtrArray> filesArray = adoptGRef(g_ptr_array_new());
+ for (GSList* file = filesList.get(); file; file = g_slist_next(file))
+ g_ptr_array_add(filesArray.get(), file->data);
+ g_ptr_array_add(filesArray.get(), 0);
+ webkit_file_chooser_request_select_files(adoptedRequest.get(), reinterpret_cast<const gchar* const*>(filesArray->pdata));
+ } else
+ webkit_file_chooser_request_cancel(adoptedRequest.get());
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+static gboolean webkitWebViewRunFileChooser(WebKitWebView* webView, WebKitFileChooserRequest* request)
+{
+ GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(webView));
+ if (!widgetIsOnscreenToplevelWindow(toplevel))
+ toplevel = 0;
+
+ gboolean allowsMultipleSelection = webkit_file_chooser_request_get_select_multiple(request);
+ GtkWidget* dialog = gtk_file_chooser_dialog_new(allowsMultipleSelection ? _("Select Files") : _("Select File"),
+ toplevel ? GTK_WINDOW(toplevel) : 0,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ if (GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(request))
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), allowsMultipleSelection);
+
+ if (const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(request))
+ gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), selectedFiles[0]);
+
+ g_signal_connect(dialog, "response", G_CALLBACK(fileChooserDialogResponseCallback), g_object_ref(request));
+ gtk_widget_show(dialog);
+
+ return TRUE;
+}
+
static void webkitWebViewConstructed(GObject* object)
{
if (G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed)
@@ -202,6 +265,8 @@ static void webkitWebViewConstructed(GObject* object)
attachLoaderClientToView(webView);
attachUIClientToView(webView);
attachPolicyClientToPage(webView);
+ attachResourceLoadClientToView(webView);
+ attachFullScreenClientToView(webView);
WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase);
priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page))));
@@ -255,7 +320,10 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu
static void webkitWebViewFinalize(GObject* object)
{
- WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate();
+ WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(object)->priv;
+ if (priv->javascriptGlobalContext)
+ JSGlobalContextRelease(priv->javascriptGlobalContext);
+ priv->~WebKitWebViewPrivate();
G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
}
@@ -290,6 +358,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
webViewClass->create = webkitWebViewCreate;
webViewClass->script_dialog = webkitWebViewScriptDialog;
webViewClass->decide_policy = webkitWebViewDecidePolicy;
+ webViewClass->run_file_chooser = webkitWebViewRunFileChooser;
g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate));
@@ -666,6 +735,104 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
webkit_marshal_BOOLEAN__OBJECT,
G_TYPE_BOOLEAN, 1,
WEBKIT_TYPE_PRINT_OPERATION);
+
+ /**
+ * WebKitWebView::resource-load-started:
+ * @web_view: the #WebKitWebView on which the signal is emitted
+ * @resource: a #WebKitWebResource
+ * @request: a #WebKitURIRequest
+ *
+ * Emitted when a new resource is going to be loaded. The @request parameter
+ * contains the #WebKitURIRequest that will be sent to the server.
+ * You can monitor the load operation by connecting to the different signals
+ * of @resource.
+ */
+ signals[RESOURCE_LOAD_STARTED] =
+ g_signal_new("resource-load-started",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, resource_load_started),
+ 0, 0,
+ webkit_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ WEBKIT_TYPE_WEB_RESOURCE,
+ WEBKIT_TYPE_URI_REQUEST);
+
+ /**
+ * WebKitWebView::enter-fullscreen:
+ * @web_view: the #WebKitWebView on which the signal is emitted.
+ *
+ * Emitted when JavaScript code calls
+ * <function>element.webkitRequestFullScreen</function>. If the
+ * signal is not handled the #WebKitWebView will proceed to full screen
+ * its top level window. This signal can be used by client code to
+ * request permission to the user prior doing the full screen
+ * transition and eventually prepare the top-level window
+ * (e.g. hide some widgets that would otherwise be part of the
+ * full screen window).
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to continue emission of the event.
+ */
+ signals[ENTER_FULLSCREEN] =
+ g_signal_new("enter-fullscreen",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, enter_fullscreen),
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ /**
+ * WebKitWebView::leave-fullscreen:
+ * @web_view: the #WebKitWebView on which the signal is emitted.
+ *
+ * Emitted when the #WebKitWebView is about to restore its top level
+ * window out of its full screen state. This signal can be used by
+ * client code to restore widgets hidden during the
+ * #WebKitWebView::enter-fullscreen stage for instance.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to continue emission of the event.
+ */
+ signals[LEAVE_FULLSCREEN] =
+ g_signal_new("leave-fullscreen",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, leave_fullscreen),
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+ /**
+ * WebKitWebView::run-file-chooser:
+ * @web_view: the #WebKitWebView on which the signal is emitted
+ * @request: a #WebKitFileChooserRequest
+ *
+ * This signal is emitted when the user interacts with a &lt;input
+ * type='file' /&gt; HTML element, requesting from WebKit to show
+ * a dialog to select one or more files to be uploaded. To let the
+ * application know the details of the file chooser, as well as to
+ * allow the client application to either cancel the request or
+ * perform an actual selection of files, the signal will pass an
+ * instance of the #WebKitFileChooserRequest in the @request
+ * argument.
+ *
+ * The default signal handler will asynchronously run a regular
+ * #GtkFileChooserDialog for the user to interact with.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ *
+ */
+ signals[RUN_FILE_CHOOSER] =
+ g_signal_new("run-file-chooser",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, run_file_chooser),
+ g_signal_accumulator_true_handled, 0 /* accumulator data */,
+ webkit_marshal_BOOLEAN__OBJECT,
+ G_TYPE_BOOLEAN, 1, /* number of parameters */
+ WEBKIT_TYPE_FILE_CHOOSER_REQUEST);
}
static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent loadEvent)
@@ -689,6 +856,12 @@ static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent l
void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
{
+ if (loadEvent == WEBKIT_LOAD_STARTED) {
+ webView->priv->loadingResourcesMap.clear();
+ webView->priv->mainResource = 0;
+ } else if (loadEvent == WEBKIT_LOAD_COMMITTED)
+ webView->priv->subresourcesMap.clear();
+
if (updateReplaceContentStatus(webView, loadEvent))
return;
@@ -822,6 +995,77 @@ void webkitWebViewPrintFrame(WebKitWebView* webView, WKFrameRef wkFrame)
g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
}
+static inline bool webkitWebViewIsReplacingContentOrDidReplaceContent(WebKitWebView* webView)
+{
+ return (webView->priv->replaceContentStatus == ReplacingContent || webView->priv->replaceContentStatus == DidReplaceContent);
+}
+
+void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WKFrameRef wkFrame, uint64_t resourceIdentifier, WebKitURIRequest* request, bool isMainResource)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return;
+
+ WebKitWebViewPrivate* priv = webView->priv;
+ WebKitWebResource* resource = webkitWebResourceCreate(wkFrame, request, isMainResource);
+ if (WKFrameIsMainFrame(wkFrame) && isMainResource)
+ priv->mainResource = resource;
+ priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource));
+ g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request);
+}
+
+WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return 0;
+
+ GRefPtr<WebKitWebResource> resource = webView->priv->loadingResourcesMap.get(resourceIdentifier);
+ ASSERT(resource.get());
+ return resource.get();
+}
+
+void webkitWebViewRemoveLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return;
+
+ WebKitWebViewPrivate* priv = webView->priv;
+ ASSERT(priv->loadingResourcesMap.contains(resourceIdentifier));
+ priv->loadingResourcesMap.remove(resourceIdentifier);
+}
+
+WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView* webView, uint64_t resourceIdentifier)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return 0;
+
+ WebKitWebViewPrivate* priv = webView->priv;
+ WebKitWebResource* resource = webkitWebViewGetLoadingWebResource(webView, resourceIdentifier);
+ if (resource != priv->mainResource)
+ priv->subresourcesMap.set(String::fromUTF8(webkit_web_resource_get_uri(resource)), resource);
+ webkitWebViewRemoveLoadingWebResource(webView, resourceIdentifier);
+ return resource;
+}
+
+bool webkitWebViewEnterFullScreen(WebKitWebView* webView)
+{
+ gboolean returnValue;
+ g_signal_emit(webView, signals[ENTER_FULLSCREEN], 0, &returnValue);
+ return !returnValue;
+}
+
+bool webkitWebViewLeaveFullScreen(WebKitWebView* webView)
+{
+ gboolean returnValue;
+ g_signal_emit(webView, signals[LEAVE_FULLSCREEN], 0, &returnValue);
+ return !returnValue;
+}
+
+void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChooserRequest* request)
+{
+ gboolean returnValue;
+ g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue);
+}
+
/**
* webkit_web_view_new:
*
@@ -1466,3 +1710,179 @@ WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView
return webView->priv->findController.get();
}
+
+/**
+ * webkit_web_view_get_javascript_global_context:
+ * @web_view: a #WebKitWebView
+ *
+ * Get the global JavaScript context used by @web_view to deserialize the
+ * result values of scripts executed with webkit_web_view_run_javascript().
+ *
+ * Returns: the <function>JSGlobalContextRef</function> used by @web_view to deserialize
+ * the result values of scripts.
+ */
+JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ if (!webView->priv->javascriptGlobalContext)
+ webView->priv->javascriptGlobalContext = JSGlobalContextCreate(0);
+ return webView->priv->javascriptGlobalContext;
+}
+
+static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSerializedScriptValue, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ if (wkSerializedScriptValue) {
+ GRefPtr<WebKitWebView> webView = adoptGRef(WEBKIT_WEB_VIEW(g_async_result_get_source_object(G_ASYNC_RESULT(result.get()))));
+ WebKitJavascriptResult* scriptResult = webkitJavascriptResultCreate(webView.get(), wkSerializedScriptValue);
+ g_simple_async_result_set_op_res_gpointer(result.get(), scriptResult, reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
+ } else {
+ GError* error = 0;
+ g_set_error_literal(&error, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, _("An exception was raised in JavaScript"));
+ g_simple_async_result_take_error(result.get(), error);
+ }
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_web_view_run_javascript:
+ * @web_view: a #WebKitWebView
+ * @script: the script to run
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously run @script in the context of the current page in @web_view.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_web_view_run_javascript_finish() to get the result of the operation.
+ */
+void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+ g_return_if_fail(script);
+
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKRetainPtr<WKStringRef> wkScript = adoptWK(WKStringCreateWithUTF8CString(script));
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_view_run_javascript));
+ WKPageRunJavaScriptInMainFrame(wkPage, wkScript.get(), result, webkitWebViewRunJavaScriptCallback);
+}
+
+/**
+ * webkit_web_view_run_javascript_finish:
+ * @web_view: a #WebKitWebView
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_view_run_javascript().
+ *
+ * This is an example of using webkit_web_view_run_javascript() with a script returning
+ * a string:
+ *
+ * <informalexample><programlisting>
+ * static void
+ * web_view_javascript_finished (GObject *object,
+ * GAsyncResult *result,
+ * gpointer user_data)
+ * {
+ * WebKitJavascriptResult *js_result;
+ * JSValueRef value;
+ * JSGlobalContextRef context;
+ * GError *error = NULL;
+ *
+ * js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
+ * if (!js_result) {
+ * g_warning ("Error running javascript: %s", error->message);
+ * g_error_free (error);
+ * return;
+ * }
+ *
+ * context = webkit_javascript_result_get_global_context (js_result);
+ * value = webkit_javascript_result_get_value (js_result);
+ * if (JSValueIsString (context, value)) {
+ * JSStringRef *js_str_value;
+ * gchar *str_value;
+ * gsize str_length;
+ *
+ * js_str_value = JSValueToStringCopy (context, value, NULL));
+ * str_length = JSStringGetMaximumUTF8CStringSize (js_str_value);
+ * str_value = (gchar *)g_malloc (str_length));
+ * JSStringGetUTF8CString (js_str_value, str_value, str_length);
+ * JSStringRelease (js_str_value);
+ * g_print ("Script result: %s\n", str_value);
+ * g_free (str_value);
+ * } else {
+ * g_warning ("Error running javascript: unexpected return value");
+ * }
+ * webkit_javascript_result_unref (js_result);
+ * }
+ *
+ * static void
+ * web_view_get_link_url (WebKitWebView *web_view,
+ * const gchar *link_id)
+ * {
+ * gchar *script;
+ *
+ * script = g_strdup_printf ("window.document.getElementById('%s').href;", link_id);
+ * webkit_web_view_run_javascript (web_view, script, web_view_javascript_finished, NULL);
+ * g_free (script);
+ * }
+ * </programlisting></informalexample>
+ *
+ * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
+ * or %NULL in case of error
+ */
+WebKitJavascriptResult* webkit_web_view_run_javascript_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_web_view_run_javascript);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return 0;
+
+ WebKitJavascriptResult* scriptResult = static_cast<WebKitJavascriptResult*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return scriptResult ? webkit_javascript_result_ref(scriptResult) : 0;
+}
+
+/**
+ * webkit_web_view_get_main_resource:
+ * @web_view: a #WebKitWebView
+ *
+ * Return the main resource of @web_view.
+ * See also webkit_web_view_get_subresources():
+ *
+ * Returns: (transfer none): the main #WebKitWebResource of the view
+ * or %NULL if nothing has been loaded.
+ */
+WebKitWebResource* webkit_web_view_get_main_resource(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ return webView->priv->mainResource.get();
+}
+
+/**
+ * webkit_web_view_get_subresources:
+ * @web_view: a #WebKitWebView
+ *
+ * Return the list of subresources of @web_view.
+ * See also webkit_web_view_get_main_resource().
+ *
+ * Returns: (element-type WebKitWebResource) (transfer container): a list of #WebKitWebResource.
+ */
+GList* webkit_web_view_get_subresources(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ GList* subresources = 0;
+ WebKitWebViewPrivate* priv = webView->priv;
+ ResourcesMap::const_iterator end = priv->subresourcesMap.end();
+ for (ResourcesMap::const_iterator it = priv->subresourcesMap.begin(); it != end; ++it)
+ subresources = g_list_prepend(subresources, it->second.get());
+
+ return g_list_reverse(subresources);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
index fb4c48a2d..c56205b96 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
@@ -28,17 +28,21 @@
#ifndef WebKitWebView_h
#define WebKitWebView_h
+#include <JavaScriptCore/JSBase.h>
#include <webkit2/WebKitBackForwardList.h>
#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitFileChooserRequest.h>
#include <webkit2/WebKitFindController.h>
#include <webkit2/WebKitHitTestResult.h>
+#include <webkit2/WebKitJavascriptResult.h>
+#include <webkit2/WebKitPolicyDecision.h>
#include <webkit2/WebKitScriptDialog.h>
#include <webkit2/WebKitSettings.h>
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitWebContext.h>
+#include <webkit2/WebKitWebResource.h>
#include <webkit2/WebKitWebViewBase.h>
#include <webkit2/WebKitWindowProperties.h>
-#include <webkit2/WebKitPolicyDecision.h>
G_BEGIN_DECLS
@@ -121,28 +125,35 @@ struct _WebKitWebView {
struct _WebKitWebViewClass {
WebKitWebViewBaseClass parent;
- void (* load_changed) (WebKitWebView *web_view,
- WebKitLoadEvent load_event);
- gboolean (* load_failed) (WebKitWebView *web_view,
- WebKitLoadEvent load_event,
- const gchar *failing_uri,
- GError *error);
-
- GtkWidget *(* create) (WebKitWebView *web_view);
- void (* ready_to_show) (WebKitWebView *web_view);
- void (* close) (WebKitWebView *web_view);
-
- gboolean (* script_dialog) (WebKitWebView *web_view,
- WebKitScriptDialog *dialog);
-
- gboolean (* decide_policy) (WebKitWebView *web_view,
- WebKitPolicyDecision *decision,
- WebKitPolicyDecisionType type);
- void (* mouse_target_changed) (WebKitWebView *web_view,
- WebKitHitTestResult *hit_test_result,
- guint modifiers);
- gboolean (* print_requested) (WebKitWebView *web_view,
- WebKitPrintOperation *print_operation);
+ void (* load_changed) (WebKitWebView *web_view,
+ WebKitLoadEvent load_event);
+ gboolean (* load_failed) (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
+ const gchar *failing_uri,
+ GError *error);
+
+ GtkWidget *(* create) (WebKitWebView *web_view);
+ void (* ready_to_show) (WebKitWebView *web_view);
+ void (* close) (WebKitWebView *web_view);
+
+ gboolean (* script_dialog) (WebKitWebView *web_view,
+ WebKitScriptDialog *dialog);
+
+ gboolean (* decide_policy) (WebKitWebView *web_view,
+ WebKitPolicyDecision *decision,
+ WebKitPolicyDecisionType type);
+ void (* mouse_target_changed) (WebKitWebView *web_view,
+ WebKitHitTestResult *hit_test_result,
+ guint modifiers);
+ gboolean (* print_requested) (WebKitWebView *web_view,
+ WebKitPrintOperation *print_operation);
+ void (* resource_load_started) (WebKitWebView *web_view,
+ WebKitWebResource *resource,
+ WebKitURIRequest *request);
+ gboolean (* enter_fullscreen) (WebKitWebView *web_view);
+ gboolean (* leave_fullscreen) (WebKitWebView *web_view);
+ gboolean (* run_file_chooser) (WebKitWebView *web_view,
+ WebKitFileChooserRequest *request);
/* Padding for future expansion */
void (*_webkit_reserved0) (void);
@@ -267,6 +278,24 @@ webkit_web_view_execute_editing_command (WebKitWebView *w
WEBKIT_API WebKitFindController *
webkit_web_view_get_find_controller (WebKitWebView *web_view);
+WEBKIT_API JSGlobalContextRef
+webkit_web_view_get_javascript_global_context (WebKitWebView *web_view);
+
+WEBKIT_API void
+webkit_web_view_run_javascript (WebKitWebView *web_view,
+ const gchar *script,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+WEBKIT_API WebKitJavascriptResult *
+webkit_web_view_run_javascript_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API WebKitWebResource *
+webkit_web_view_get_main_resource (WebKitWebView *web_view);
+
+WEBKIT_API GList *
+webkit_web_view_get_subresources (WebKitWebView *web_view);
G_END_DECLS
#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
index adcc34ae3..b2cdde564 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -35,6 +35,7 @@
#include "PageClientImpl.h"
#include "WebContext.h"
#include "WebEventFactory.h"
+#include "WebFullScreenClientGtk.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBaseAccessible.h"
#include "WebKitWebViewBasePrivate.h"
@@ -52,14 +53,24 @@
#include <WebCore/PasteboardHelper.h>
#include <WebCore/RefPtrCairo.h>
#include <WebCore/Region.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <wtf/HashMap.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
+#if ENABLE(FULLSCREEN_API)
+#include "WebFullScreenManagerProxy.h"
+#endif
+
using namespace WebKit;
using namespace WebCore;
+typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap;
+
struct _WebKitWebViewBasePrivate {
+ WebKitWebViewChildrenMap children;
OwnPtr<PageClientImpl> pageClient;
RefPtr<WebPageProxy> pageProxy;
bool isPageActive;
@@ -72,6 +83,10 @@ struct _WebKitWebViewBasePrivate {
IntSize resizerSize;
GRefPtr<AtkObject> accessible;
bool needsResizeOnMap;
+#if ENABLE(FULLSCREEN_API)
+ bool fullScreenModeActive;
+ WebFullScreenClientGtk fullScreenClient;
+#endif
};
G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
@@ -152,9 +167,53 @@ static void webkitWebViewBaseRealize(GtkWidget* widget)
static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* widget)
{
+ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
+ WebKitWebViewBasePrivate* priv = webView->priv;
+
+ GtkAllocation childAllocation;
+ gtk_widget_get_allocation(widget, &childAllocation);
+ priv->children.set(widget, childAllocation);
+
gtk_widget_set_parent(widget, GTK_WIDGET(container));
}
+static void webkitWebViewBaseContainerRemove(GtkContainer* container, GtkWidget* widget)
+{
+ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
+ WebKitWebViewBasePrivate* priv = webView->priv;
+ GtkWidget* widgetContainer = GTK_WIDGET(container);
+
+ ASSERT(priv->children.contains(widget));
+ gboolean wasVisible = gtk_widget_get_visible(widget);
+ gtk_widget_unparent(widget);
+
+ priv->children.remove(widget);
+ if (wasVisible && gtk_widget_get_visible(widgetContainer))
+ gtk_widget_queue_resize(widgetContainer);
+}
+
+static void webkitWebViewBaseContainerForall(GtkContainer* container, gboolean includeInternals, GtkCallback callback, gpointer callbackData)
+{
+ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
+ WebKitWebViewBasePrivate* priv = webView->priv;
+
+ WebKitWebViewChildrenMap children = priv->children;
+ WebKitWebViewChildrenMap::const_iterator end = children.end();
+ for (WebKitWebViewChildrenMap::const_iterator current = children.begin(); current != end; ++current)
+ (*callback)(current->first, callbackData);
+}
+
+void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* child, const IntRect& childRect)
+{
+ const IntRect& geometry = webView->priv->children.get(child);
+
+ if (geometry == childRect)
+ return;
+
+ webView->priv->children.set(child, childRect);
+ gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webView));
+}
+
static void webkitWebViewBaseFinalize(GObject* gobject)
{
WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(gobject);
@@ -203,10 +262,27 @@ static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr)
return FALSE;
}
-static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase, GtkAllocation* allocation)
+static void webkitWebViewBaseChildAllocate(GtkWidget* child, gpointer userData)
{
+ if (!gtk_widget_get_visible(child))
+ return;
+
+ WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(userData);
WebKitWebViewBasePrivate* priv = webViewBase->priv;
+ const IntRect& geometry = priv->children.get(child);
+ if (geometry.isEmpty())
+ return;
+
+ GtkAllocation childAllocation = geometry;
+ gtk_widget_size_allocate(child, &childAllocation);
+ priv->children.set(child, IntRect());
+}
+
+static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase, GtkAllocation* allocation)
+{
+ gtk_container_foreach(GTK_CONTAINER(webViewBase), webkitWebViewBaseChildAllocate, webViewBase);
+ WebKitWebViewBasePrivate* priv = webViewBase->priv;
if (priv->pageProxy->drawingArea())
priv->pageProxy->drawingArea()->setSize(IntSize(allocation->width, allocation->height), IntSize());
@@ -239,7 +315,6 @@ static void webkitWebViewBaseMap(GtkWidget* widget)
gtk_widget_get_allocation(widget, &allocation);
resizeWebKitWebViewBaseFromAllocation(webViewBase, &allocation);
webViewBase->priv->needsResizeOnMap = false;
-
}
static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event)
@@ -277,6 +352,20 @@ static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* e
WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
WebKitWebViewBasePrivate* priv = webViewBase->priv;
+#if ENABLE(FULLSCREEN_API)
+ if (priv->fullScreenModeActive) {
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ case GDK_KEY_f:
+ case GDK_KEY_F:
+ webkitWebViewBaseExitFullScreen(webViewBase);
+ return TRUE;
+ default:
+ break;
+ }
+ }
+#endif
+
// Since WebProcess key event handling is not synchronous, handle the event in two passes.
// When WebProcess processes the input event, it will call PageClientImpl::doneWithKeyEvent
// with event handled status which determines whether to pass the input event to parent or not
@@ -467,7 +556,8 @@ static gboolean webkitWebViewBaseDragDrop(GtkWidget* widget, GdkDragContext* con
return FALSE;
SandboxExtension::Handle handle;
- webViewBase->priv->pageProxy->performDrag(dragData.get(), String(), handle);
+ SandboxExtension::HandleArray sandboxExtensionForUpload;
+ webViewBase->priv->pageProxy->performDrag(dragData.get(), String(), handle, sandboxExtensionForUpload);
gtk_drag_finish(context, TRUE, FALSE, time);
return TRUE;
}
@@ -501,6 +591,8 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie
GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webkitWebViewBaseClass);
containerClass->add = webkitWebViewBaseContainerAdd;
+ containerClass->remove = webkitWebViewBaseContainerRemove;
+ containerClass->forall = webkitWebViewBaseContainerForall;
g_type_class_add_private(webkitWebViewBaseClass, sizeof(WebKitWebViewBasePrivate));
}
@@ -528,6 +620,10 @@ void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, WKCont
priv->pageProxy = toImpl(context)->createWebPage(priv->pageClient.get(), toImpl(pageGroup));
priv->pageProxy->initializeWebPage();
+
+#if ENABLE(FULLSCREEN_API)
+ priv->pageProxy->fullScreenManager()->setWebView(webkitWebViewBase);
+#endif
}
void webkitWebViewBaseSetTooltipText(WebKitWebViewBase* webViewBase, const char* tooltip)
@@ -575,3 +671,50 @@ void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase* webkitWebViewBase)
{
webkitWebViewBase->priv->shouldForwardNextKeyEvent = TRUE;
}
+
+void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase)
+{
+#if ENABLE(FULLSCREEN_API)
+ WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
+ if (priv->fullScreenModeActive)
+ return;
+
+ if (!priv->fullScreenClient.willEnterFullScreen())
+ return;
+
+ WebFullScreenManagerProxy* fullScreenManagerProxy = priv->pageProxy->fullScreenManager();
+ fullScreenManagerProxy->willEnterFullScreen();
+
+ GtkWidget* topLevelWindow = gtk_widget_get_toplevel(GTK_WIDGET(webkitWebViewBase));
+ if (gtk_widget_is_toplevel(topLevelWindow))
+ gtk_window_fullscreen(GTK_WINDOW(topLevelWindow));
+ fullScreenManagerProxy->didEnterFullScreen();
+ priv->fullScreenModeActive = true;
+#endif
+}
+
+void webkitWebViewBaseExitFullScreen(WebKitWebViewBase* webkitWebViewBase)
+{
+#if ENABLE(FULLSCREEN_API)
+ WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
+ if (!priv->fullScreenModeActive)
+ return;
+
+ if (!priv->fullScreenClient.willExitFullScreen())
+ return;
+
+ WebFullScreenManagerProxy* fullScreenManagerProxy = priv->pageProxy->fullScreenManager();
+ fullScreenManagerProxy->willExitFullScreen();
+
+ GtkWidget* topLevelWindow = gtk_widget_get_toplevel(GTK_WIDGET(webkitWebViewBase));
+ if (gtk_widget_is_toplevel(topLevelWindow))
+ gtk_window_unfullscreen(GTK_WINDOW(topLevelWindow));
+ fullScreenManagerProxy->didExitFullScreen();
+ priv->fullScreenModeActive = false;
+#endif
+}
+
+void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase* webkitWebViewBase, const WKFullScreenClientGtk* wkClient)
+{
+ webkitWebViewBase->priv->fullScreenClient.initialize(wkClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index 3a9a40b86..cd4c1a1b5 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -28,28 +28,22 @@
#ifndef WebKitWebViewBasePrivate_h
#define WebKitWebViewBasePrivate_h
+#include "WebKitPrivate.h"
#include "WebKitWebViewBase.h"
#include "WebPageProxy.h"
-#include <WebKit2/WebKit2.h>
using namespace WebKit;
-G_BEGIN_DECLS
-
WebKitWebViewBase* webkitWebViewBaseCreate(WebContext*, WebPageGroup*);
-
GtkIMContext* webkitWebViewBaseGetIMContext(WebKitWebViewBase*);
-
WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase*);
-
void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, WKContextRef, WKPageGroupRef);
-
void webkitWebViewBaseSetTooltipText(WebKitWebViewBase*, const char*);
-
void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase*);
-
void webkitWebViewBaseStartDrag(WebKitWebViewBase*, const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage);
-
-G_END_DECLS
+void webkitWebViewBaseChildMoveResize(WebKitWebViewBase*, GtkWidget*, const WebCore::IntRect&);
+void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase*);
+void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*);
+void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase*, const WKFullScreenClientGtk*);
#endif // WebKitWebViewBasePrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
index ad8ab2038..717d2c344 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
@@ -45,5 +45,12 @@ WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& mess
void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*);
void webkitWebViewMouseTargetChanged(WebKitWebView*, WKHitTestResultRef, unsigned modifiers);
void webkitWebViewPrintFrame(WebKitWebView*, WKFrameRef);
+void webkitWebViewResourceLoadStarted(WebKitWebView*, WKFrameRef, uint64_t resourceIdentifier, WebKitURIRequest*, bool isMainResource);
+void webkitWebViewRunFileChooserRequest(WebKitWebView*, WebKitFileChooserRequest*);
+WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
+void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
+WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView*, uint64_t resourceIdentifier);
+bool webkitWebViewEnterFullScreen(WebKitWebView*);
+bool webkitWebViewLeaveFullScreen(WebKitWebView*);
#endif // WebKitWebViewPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
index 4a9cc798c..821127f3d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
@@ -26,8 +26,11 @@
<xi:include href="xml/WebKitResponsePolicyDecision.xml"/>
<xi:include href="xml/WebKitHitTestResult.xml"/>
<xi:include href="xml/WebKitPrintOperation.xml"/>
+ <xi:include href="xml/WebKitWebResource.xml"/>
<xi:include href="xml/WebKitError.xml"/>
+ <xi:include href="xml/WebKitFileChooserRequest.xml"/>
<xi:include href="xml/WebKitFindController.xml"/>
+ <xi:include href="xml/WebKitCookieManager.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 a8f54083a..dc5e65ac6 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
@@ -28,6 +28,7 @@ webkit_web_context_get_default
webkit_web_context_get_cache_model
webkit_web_context_set_cache_model
webkit_web_context_download_uri
+webkit_web_context_get_cookie_manager
<SUBSECTION Standard>
WebKitWebContextClass
@@ -49,8 +50,6 @@ webkit_web_context_get_type
WebKitWebView
WebKitLoadEvent
WebKitPolicyDecisionType
-WebKitScriptDialog
-WebKitScriptDialogType
<SUBSECTION Editing Commands>
WEBKIT_EDITING_COMMAND_CUT
@@ -89,11 +88,27 @@ 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_web_view_get_javascript_global_context
+webkit_web_view_run_javascript
+webkit_web_view_run_javascript_finish
+
+<SUBSECTION WebKitJavascriptResult>
+WebKitJavascriptResult
+webkit_javascript_result_ref
+webkit_javascript_result_unref
+webkit_javascript_result_get_global_context
+webkit_javascript_result_get_value
+
+<SUBSECTION WebKitScriptDialog>
+WebKitScriptDialog
+WebKitScriptDialogType
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
+webkit_web_view_get_main_resource
+webkit_web_view_get_subresources
<SUBSECTION Standard>
WebKitWebViewClass
@@ -103,10 +118,12 @@ WEBKIT_TYPE_WEB_VIEW
WEBKIT_WEB_VIEW_CLASS
WEBKIT_IS_WEB_VIEW_CLASS
WEBKIT_WEB_VIEW_GET_CLASS
+WEBKIT_TYPE_JAVASCRIPT_RESULT
WEBKIT_TYPE_SCRIPT_DIALOG
<SUBSECTION Private>
webkit_web_view_get_type
+webkit_javascript_result_get_type
webkit_script_dialog_get_type
WebKitWebViewPrivate
</SECTION>
@@ -232,6 +249,8 @@ webkit_settings_get_enable_webgl
webkit_settings_set_enable_webgl
webkit_settings_get_zoom_text_only
webkit_settings_set_zoom_text_only
+webkit_settings_get_javascript_can_access_clipboard
+webkit_settings_set_javascript_can_access_clipboard
<SUBSECTION Standard>
WebKitSettingsClass
@@ -458,19 +477,71 @@ webkit_print_operation_get_type
</SECTION>
<SECTION>
+<FILE>WebKitWebResource</FILE>
+WebKitWebResource
+webkit_web_resource_get_uri
+webkit_web_resource_get_response
+webkit_web_resource_get_data
+webkit_web_resource_get_data_finish
+
+<SUBSECTION Standard>
+WebKitWebResourceClass
+WEBKIT_TYPE_WEB_RESOURCE
+WEBKIT_WEB_RESOURCE
+WEBKIT_IS_WEB_RESOURCE
+WEBKIT_WEB_RESOURCE_CLASS
+WEBKIT_IS_WEB_RESOURCE_CLASS
+WEBKIT_WEB_RESOURCE_GET_CLASS
+
+<SUBSECTION Private>
+WebKitWebResourcePrivate
+webkit_web_resource_get_type
+</SECTION>
+
+<SECTION>
<FILE>WebKitError</FILE>
WEBKIT_NETWORK_ERROR
WEBKIT_PLUGIN_ERROR
WEBKIT_POLICY_ERROR
WEBKIT_DOWNLOAD_ERROR
+WEBKIT_PRINT_ERROR
+WEBKIT_JAVASCRIPT_ERROR
WebKitNetworkError
WebKitPluginError
WebKitPolicyError
WebKitDownloadError
+WebKitPrintError
+WebKitJavascriptError
webkit_network_error_quark
webkit_plugin_error_quark
webkit_policy_error_quark
webkit_download_error_quark
+webkit_print_error_quark
+webkit_javascript_error_quark
+</SECTION>
+
+<SECTION>
+<FILE>WebKitFileChooserRequest</FILE>
+WebKitFileChooserRequest
+webkit_file_chooser_request_get_mime_types
+webkit_file_chooser_request_get_mime_types_filter
+webkit_file_chooser_request_get_select_multiple
+webkit_file_chooser_request_select_files
+webkit_file_chooser_request_get_selected_files
+webkit_file_chooser_request_cancel
+
+<SUBSECTION Standard>
+WebKitFileChooserRequestClass
+WEBKIT_TYPE_FILE_CHOOSER_REQUEST
+WEBKIT_FILE_CHOOSER_REQUEST
+WEBKIT_IS_FILE_CHOOSER_REQUEST
+WEBKIT_FILE_CHOOSER_REQUEST_CLASS
+WEBKIT_IS_FILE_CHOOSER_REQUEST_CLASS
+WEBKIT_FILE_CHOOSER_REQUEST_GET_CLASS
+
+<SUBSECTION Private>
+WebKitFileChooserRequestPrivate
+webkit_file_chooser_request_get_type
</SECTION>
<SECTION>
@@ -500,3 +571,29 @@ WEBKIT_FIND_CONTROLLER_GET_CLASS
WebKitFindControllerPrivate
webkit_find_controller_get_type
</SECTION>
+
+<SECTION>
+<FILE>WebKitCookieManager</FILE>
+WebKitCookieManager
+WebKitCookieAcceptPolicy
+webkit_cookie_manager_set_accept_policy
+webkit_cookie_manager_get_accept_policy
+webkit_cookie_manager_get_accept_policy_finish
+webkit_cookie_manager_get_domains_with_cookies
+webkit_cookie_manager_get_domains_with_cookies_finish
+webkit_cookie_manager_delete_cookies_for_domain
+webkit_cookie_manager_delete_all_cookies
+
+<SUBSECTION Standard>
+WebKitCookieManagerClass
+WEBKIT_TYPE_COOKIE_MANAGER
+WEBKIT_COOKIE_MANAGER
+WEBKIT_IS_COOKIE_MANAGER
+WEBKIT_COOKIE_MANAGER_CLASS
+WEBKIT_IS_COOKIE_MANAGER_CLASS
+WEBKIT_COOKIE_MANAGER_GET_CLASS
+
+<SUBSECTION Private>
+WebKitCookieManagerPrivate
+webkit_cookie_manager_get_type
+</SECTION>
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
index 8e8d7b13a..1ca821b47 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
@@ -9,5 +9,9 @@ webkit_uri_response_get_type
webkit_uri_request_get_type
webkit_window_properties_get_type
webkit_download_get_type
+webkit_file_chooser_request_get_type
webkit_find_controller_get_type
webkit_script_dialog_get_type
+webkit_javascript_result_get_type
+webkit_web_resource_get_type
+webkit_cookie_manager_get_type
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
index 6adb2d5cd..b389f4954 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
@@ -2,9 +2,11 @@ if ENABLE_WEBKIT2
TEST_PROGS += \
Programs/WebKit2APITests/TestBackForwardList \
+ Programs/WebKit2APITests/TestCookieManager \
Programs/WebKit2APITests/TestDownloads \
Programs/WebKit2APITests/TestLoaderClient \
Programs/WebKit2APITests/TestPrinting \
+ Programs/WebKit2APITests/TestResources \
Programs/WebKit2APITests/TestWebKitFindController \
Programs/WebKit2APITests/TestWebKitPolicyClient \
Programs/WebKit2APITests/TestWebKitSettings \
@@ -135,4 +137,16 @@ Programs_WebKit2APITests_TestWebKitFindController_CPPFLAGS = $(webkit2_tests_cpp
Programs_WebKit2APITests_TestWebKitFindController_LDADD = $(webkit2_tests_ldadd)
Programs_WebKit2APITests_TestWebKitFindController_LDFLAGS = $(webkit2_tests_ldflags)
+Programs_WebKit2APITests_TestResources_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
+Programs_WebKit2APITests_TestResources_CPPFLAGS = $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestResources_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestResources_LDFLAGS = $(webkit2_tests_ldflags)
+
+Programs_WebKit2APITests_TestCookieManager_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
+Programs_WebKit2APITests_TestCookieManager_CPPFLAGS = $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestCookieManager_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestCookieManager_LDFLAGS = $(webkit2_tests_ldflags)
+
endif # ENABLE_WEBKIT2
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
new file mode 100644
index 000000000..6d2ecf528
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
@@ -0,0 +1,239 @@
+/*
+ * 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 "WebKitTestServer.h"
+#include "WebViewTest.h"
+
+static WebKitTestServer* kServer;
+
+static const char* kFirstPartyDomain = "127.0.0.1";
+static const char* kThirdPartyDomain = "localhost";
+static const char* kIndexHtmlFormat =
+ "<html><body>"
+ " <p>WebKitGTK+ Cookie Manager test</p>"
+ " <img src='http://localhost:%u/image.png' width=5 height=5></img>"
+ "</body></html>";
+
+class CookieManagerTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(CookieManagerTest);
+
+ static void cookiesChangedCallback(WebKitCookieManager*, CookieManagerTest* test)
+ {
+ test->m_cookiesChanged = true;
+ if (test->m_finishLoopWhenCookiesChange)
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ CookieManagerTest()
+ : WebViewTest()
+ , m_cookieManager(webkit_web_context_get_cookie_manager(webkit_web_view_get_context(m_webView)))
+ , m_acceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY)
+ , m_domains(0)
+ , m_cookiesChanged(false)
+ , m_finishLoopWhenCookiesChange(false)
+ {
+ g_signal_connect(m_cookieManager, "changed", G_CALLBACK(cookiesChangedCallback), this);
+ }
+
+ ~CookieManagerTest()
+ {
+ g_strfreev(m_domains);
+ g_signal_handlers_disconnect_matched(m_cookieManager, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ }
+
+ static void getAcceptPolicyReadyCallback(GObject* object, GAsyncResult* result, gpointer userData)
+ {
+ GOwnPtr<GError> error;
+ WebKitCookieAcceptPolicy policy = webkit_cookie_manager_get_accept_policy_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr());
+ g_assert(!error.get());
+
+ CookieManagerTest* test = static_cast<CookieManagerTest*>(userData);
+ test->m_acceptPolicy = policy;
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ WebKitCookieAcceptPolicy getAcceptPolicy()
+ {
+ m_acceptPolicy = WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
+ webkit_cookie_manager_get_accept_policy(m_cookieManager, getAcceptPolicyReadyCallback, this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_acceptPolicy;
+ }
+
+ void setAcceptPolicy(WebKitCookieAcceptPolicy policy)
+ {
+ webkit_cookie_manager_set_accept_policy(m_cookieManager, policy);
+ }
+
+ static void getDomainsReadyCallback(GObject* object, GAsyncResult* result, gpointer userData)
+ {
+ GOwnPtr<GError> error;
+ char** domains = webkit_cookie_manager_get_domains_with_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr());
+ g_assert(!error.get());
+
+ CookieManagerTest* test = static_cast<CookieManagerTest*>(userData);
+ test->m_domains = domains;
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ char** getDomains()
+ {
+ g_strfreev(m_domains);
+ m_domains = 0;
+ webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, getDomainsReadyCallback, this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_domains;
+ }
+
+ void deleteCookiesForDomain(const char* domain)
+ {
+ webkit_cookie_manager_delete_cookies_for_domain(m_cookieManager, domain);
+ }
+
+ void deleteAllCookies()
+ {
+ webkit_cookie_manager_delete_all_cookies(m_cookieManager);
+ }
+
+ void waitUntilCookiesChanged()
+ {
+ m_cookiesChanged = false;
+ m_finishLoopWhenCookiesChange = true;
+ g_main_loop_run(m_mainLoop);
+ m_finishLoopWhenCookiesChange = false;
+ }
+
+ WebKitCookieManager* m_cookieManager;
+ WebKitCookieAcceptPolicy m_acceptPolicy;
+ char** m_domains;
+ bool m_cookiesChanged;
+ bool m_finishLoopWhenCookiesChange;
+};
+
+static void testCookieManagerAcceptPolicy(CookieManagerTest* test, gconstpointer)
+{
+ // Default policy is NO_THIRD_PARTY.
+ g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ char** domains = test->getDomains();
+ g_assert(domains);
+ g_assert_cmpint(g_strv_length(domains), ==, 1);
+ g_assert_cmpstr(domains[0], ==, kFirstPartyDomain);
+ test->deleteAllCookies();
+
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ domains = test->getDomains();
+ g_assert(domains);
+ g_assert_cmpint(g_strv_length(domains), ==, 2);
+ g_assert_cmpstr(domains[0], ==, kFirstPartyDomain);
+ g_assert_cmpstr(domains[1], ==, kThirdPartyDomain);
+ test->deleteAllCookies();
+
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER);
+ g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NEVER);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ domains = test->getDomains();
+ g_assert(domains);
+ g_assert_cmpint(g_strv_length(domains), ==, 0);
+}
+
+static void testCookieManagerDeleteCookies(CookieManagerTest* test, gconstpointer)
+{
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2);
+
+ // Delete first party cookies.
+ test->deleteCookiesForDomain(kFirstPartyDomain);
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1);
+
+ // Delete third party cookies.
+ test->deleteCookiesForDomain(kThirdPartyDomain);
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0);
+
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2);
+
+ // Delete all cookies.
+ test->deleteAllCookies();
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0);
+}
+
+static void testCookieManagerCookiesChanged(CookieManagerTest* test, gconstpointer)
+{
+ g_assert(!test->m_cookiesChanged);
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ g_assert(test->m_cookiesChanged);
+
+ test->deleteCookiesForDomain(kFirstPartyDomain);
+ test->waitUntilCookiesChanged();
+ g_assert(test->m_cookiesChanged);
+
+ test->deleteAllCookies();
+ test->waitUntilCookiesChanged();
+ g_assert(test->m_cookiesChanged);
+}
+
+static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
+{
+ if (message->method != SOUP_METHOD_GET) {
+ soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ if (g_str_equal(path, "/index.html")) {
+ char* indexHtml = g_strdup_printf(kIndexHtmlFormat, soup_server_get_port(server));
+ soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar");
+ soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, indexHtml, strlen(indexHtml));
+ } else if (g_str_equal(path, "/image.png"))
+ soup_message_headers_replace(message->response_headers, "Set-Cookie", "baz=qux");
+ else
+ g_assert_not_reached();
+ soup_message_body_complete(message->response_body);
+}
+
+void beforeAll()
+{
+ kServer = new WebKitTestServer();
+ kServer->run(serverCallback);
+
+ CookieManagerTest::add("WebKitCookieManager", "accept-policy", testCookieManagerAcceptPolicy);
+ CookieManagerTest::add("WebKitCookieManager", "delete-cookies", testCookieManagerDeleteCookies);
+ CookieManagerTest::add("WebKitCookieManager", "cookies-changed", testCookieManagerCookiesChanged);
+}
+
+void afterAll()
+{
+ delete kServer;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp
index 461cefa0e..a119e4477 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp
@@ -173,15 +173,9 @@ public:
guint64 m_downloadSize;
};
-static CString getWebKit1TestResoucesDir()
-{
- GOwnPtr<char> resourcesDir(g_build_filename(WEBKIT_SRC_DIR, "Source", "WebKit", "gtk", "tests", "resources", NULL));
- return resourcesDir.get();
-}
-
static void testDownloadLocalFile(DownloadTest* test, gconstpointer)
{
- GOwnPtr<char> sourcePath(g_build_filename(getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
+ GOwnPtr<char> sourcePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get()));
GRefPtr<GFileInfo> sourceInfo = adoptGRef(g_file_query_info(source.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0));
GOwnPtr<char> sourceURI(g_file_get_uri(source.get()));
@@ -258,7 +252,7 @@ static void testDownloadLocalFileError(DownloadErrorTest* test, gconstpointer)
g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
test->m_expectedError = WEBKIT_DOWNLOAD_ERROR_DESTINATION;
- GOwnPtr<char> path(g_build_filename(getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
+ GOwnPtr<char> path(g_build_filename(Test::getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get()));
GOwnPtr<char> uri(g_file_get_uri(file.get()));
download = adoptGRef(webkit_web_context_download_uri(test->m_webContext, uri.get()));
@@ -301,7 +295,7 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char*
return;
}
- GOwnPtr<char> filePath(g_build_filename(getWebKit1TestResoucesDir().data(), path, NULL));
+ GOwnPtr<char> filePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), path, NULL));
char* contents;
gsize contentsLength;
if (!g_file_get_contents(filePath.get(), &contents, &contentsLength, 0)) {
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h b/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h
index 39a2000ac..219cb44ed 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h
@@ -20,9 +20,10 @@
#ifndef TestMain_h
#define TestMain_h
-#include <JavaScriptCore/GOwnPtr.h>
-#include <JavaScriptCore/HashSet.h>
#include <glib-object.h>
+#include <wtf/HashSet.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/text/CString.h>
#define MAKE_GLIB_TEST_FIXTURE(ClassName) \
static void setUp(ClassName* fixture, gconstpointer data) \
@@ -45,6 +46,15 @@ public:
~Test()
{
+ if (m_watchedObjects.isEmpty())
+ return;
+
+ g_print("Leaked objects:");
+ HashSet<GObject*>::const_iterator end = m_watchedObjects.end();
+ for (HashSet<GObject*>::const_iterator it = m_watchedObjects.begin(); it != end; ++it)
+ g_print(" %s(%p)", g_type_name_from_instance(reinterpret_cast<GTypeInstance*>(*it)), *it);
+ g_print("\n");
+
g_assert(m_watchedObjects.isEmpty());
}
@@ -59,6 +69,12 @@ public:
g_object_weak_ref(object, reinterpret_cast<GWeakNotify>(objectFinalized), this);
}
+ static CString getWebKit1TestResoucesDir()
+ {
+ GOwnPtr<char> resourcesDir(g_build_filename(WEBKIT_SRC_DIR, "Source", "WebKit", "gtk", "tests", "resources", NULL));
+ return resourcesDir.get();
+ }
+
HashSet<GObject*> m_watchedObjects;
};
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp
index 1ddde0858..150c31bd3 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp
@@ -72,37 +72,63 @@ static void testWebViewPrintRequested(WebViewTest* test, gconstpointer)
}
#ifdef HAVE_GTK_UNIX_PRINTING
-static void testPrintOperationPrintLoadChanged(WebKitWebView*, WebKitLoadEvent loadEvent, WebViewTest* test)
-{
- if (loadEvent != WEBKIT_LOAD_FINISHED)
- return;
- g_main_loop_quit(test->m_mainLoop);
-}
+class PrintTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(PrintTest);
-static void testPrintOperationPrintFinished(WebKitPrintOperation* printOperation, WebViewTest* test)
-{
- g_object_unref(printOperation);
- g_main_loop_quit(test->m_mainLoop);
-}
+ static void printFinishedCallback(WebKitPrintOperation*, PrintTest* test)
+ {
+ g_main_loop_quit(test->m_mainLoop);
+ }
-static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData)
-{
- if (strcmp(gtk_printer_get_name(printer), "Print to File"))
- return FALSE;
+ static void printFailedCallback(WebKitPrintOperation*, GError* error, PrintTest* test)
+ {
+ g_assert(test->m_expectedError);
+ g_assert(error);
+ g_assert(g_error_matches(error, WEBKIT_PRINT_ERROR, test->m_expectedError));
+ }
- GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData);
- *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer));
- return TRUE;
-}
+ PrintTest()
+ : m_expectedError(0)
+ {
+ m_printOperation = adoptGRef(webkit_print_operation_new(m_webView));
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get()));
+ g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printFinishedCallback), this);
+ g_signal_connect(m_printOperation.get(), "failed", G_CALLBACK(printFailedCallback), this);
+ }
+
+ static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData)
+ {
+ if (strcmp(gtk_printer_get_name(printer), "Print to File"))
+ return FALSE;
+
+ GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData);
+ *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer));
+ return TRUE;
+ }
+
+ GtkPrinter* findPrintToFilePrinter()
+ {
+ GtkPrinter* printer = 0;
+ gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE);
+ return printer;
+ }
-static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
+ void waitUntilPrintFinished()
+ {
+ g_main_loop_run(m_mainLoop);
+ }
+
+ GRefPtr<WebKitPrintOperation> m_printOperation;
+ unsigned int m_expectedError;
+};
+
+static void testPrintOperationPrint(PrintTest* test, gconstpointer)
{
- g_signal_connect(test->m_webView, "load-changed", G_CALLBACK(testPrintOperationPrintLoadChanged), test);
test->loadHtml("<html><body>WebKitGTK+ printing test</body></html>", 0);
- g_main_loop_run(test->m_mainLoop);
+ test->waitUntilLoadFinished();
- GtkPrinter* printer = 0;
- gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE);
+ GRefPtr<GtkPrinter> printer = adoptGRef(test->findPrintToFilePrinter());
if (!printer) {
g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
return;
@@ -113,16 +139,12 @@ static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
GOwnPtr<char> outputURI(g_file_get_uri(outputFile.get()));
GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
- gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer));
+ gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get());
- g_object_unref(printer);
- GRefPtr<WebKitPrintOperation> printOperation = webkit_print_operation_new(test->m_webView);
- test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation.get()));
- g_signal_connect(printOperation.get(), "finished", G_CALLBACK(testPrintOperationPrintFinished), test);
- webkit_print_operation_set_print_settings(printOperation.get(), printSettings.get());
- webkit_print_operation_print(printOperation.get());
- g_main_loop_run(test->m_mainLoop);
+ webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(outputFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE","G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
static_cast<GFileQueryInfoFlags>(0), 0, 0));
@@ -132,6 +154,40 @@ static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
g_file_delete(outputFile.get(), 0, 0);
}
+
+static void testPrintOperationErrors(PrintTest* test, gconstpointer)
+{
+ test->loadHtml("<html><body>WebKitGTK+ printing errors test</body></html>", 0);
+ test->waitUntilLoadFinished();
+
+ GRefPtr<GtkPrinter> printer = adoptGRef(test->findPrintToFilePrinter());
+ if (!printer) {
+ g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
+ return;
+ }
+
+ // General Error: invalid filename.
+ test->m_expectedError = WEBKIT_PRINT_ERROR_GENERAL;
+ GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
+ gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
+ gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, "file:///foo/bar");
+ webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
+
+ // Printer not found error.
+ test->m_expectedError = WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND;
+ gtk_print_settings_set_printer(printSettings.get(), "The fake WebKit printer");
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
+
+ // No pages to print: print even pages for a single page document.
+ test->m_expectedError = WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE;
+ gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
+ gtk_print_settings_set_page_set(printSettings.get(), GTK_PAGE_SET_EVEN);
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
+}
#endif // HAVE_GTK_UNIX_PRINTING
void beforeAll()
@@ -142,7 +198,8 @@ void beforeAll()
WebViewTest::add("WebKitPrintOperation", "printing-settings", testPrintOperationPrintSettings);
WebViewTest::add("WebKitWebView", "print-requested", testWebViewPrintRequested);
#ifdef HAVE_GTK_UNIX_PRINTING
- WebViewTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
+ PrintTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
+ PrintTest::add("WebKitPrintOperation", "print-errors", testPrintOperationErrors);
#endif
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
new file mode 100644
index 000000000..cc272c9e8
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
@@ -0,0 +1,596 @@
+/*
+ * 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 "WebKitTestServer.h"
+#include "WebViewTest.h"
+#include <wtf/gobject/GRefPtr.h>
+
+static WebKitTestServer* kServer;
+
+static const char* kIndexHtml =
+ "<html><head>"
+ " <link rel='stylesheet' href='/style.css' type='text/css'>"
+ " <script language='javascript' src='/javascript.js'></script>"
+ "</head><body>WebKitGTK+ resources test</body></html>";
+
+static const char* kStyleCSS =
+ "body {"
+ " margin: 0px;"
+ " padding: 0px;"
+ " font-family: sans-serif;"
+ " background: url(/blank.ico) 0 0 no-repeat;"
+ " color: black;"
+ "}";
+
+static const char* kJavascript = "function foo () { var a = 1; }";
+
+class ResourcesTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ResourcesTest);
+
+ static void resourceSentRequestCallback(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse, ResourcesTest* test)
+ {
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ if (redirectResponse)
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(redirectResponse));
+ test->resourceSentRequest(resource, request, redirectResponse);
+ }
+
+ static void resourceReceivedResponseCallback(WebKitWebResource* resource, GParamSpec*, ResourcesTest* test)
+ {
+ g_assert(webkit_web_resource_get_response(resource));
+ test->resourceReceivedResponse(resource);
+ }
+
+ static void resourceReceivedDataCallback(WebKitWebResource* resource, guint64 bytesReceived, ResourcesTest* test)
+ {
+ test->resourceReceivedData(resource, bytesReceived);
+ }
+
+ static void resourceFinishedCallback(WebKitWebResource* resource, ResourcesTest* test)
+ {
+ test->resourceFinished(resource);
+ }
+
+ static void resourceFailedCallback(WebKitWebResource* resource, GError* error, ResourcesTest* test)
+ {
+ g_assert(error);
+ test->resourceFailed(resource, error);
+ }
+
+ static void resourceLoadStartedCallback(WebKitWebView* webView, WebKitWebResource* resource, WebKitURIRequest* request, ResourcesTest* test)
+ {
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resource));
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ test->resourceLoadStarted(resource, request);
+ g_signal_connect(resource, "sent-request", G_CALLBACK(resourceSentRequestCallback), test);
+ g_signal_connect(resource, "notify::response", G_CALLBACK(resourceReceivedResponseCallback), test);
+ g_signal_connect(resource, "received-data", G_CALLBACK(resourceReceivedDataCallback), test);
+ g_signal_connect(resource, "finished", G_CALLBACK(resourceFinishedCallback), test);
+ g_signal_connect(resource, "failed", G_CALLBACK(resourceFailedCallback), test);
+ }
+
+ ResourcesTest()
+ : WebViewTest()
+ , m_resourcesLoaded(0)
+ , m_resourcesToLoad(0)
+ , m_resourceDataSize(0)
+ {
+ g_signal_connect(m_webView, "resource-load-started", G_CALLBACK(resourceLoadStartedCallback), this);
+ }
+
+ virtual void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request)
+ {
+ }
+
+ virtual void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+ {
+ }
+
+ virtual void resourceReceivedResponse(WebKitWebResource* resource)
+ {
+ }
+
+ virtual void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived)
+ {
+ }
+
+ virtual void resourceFinished(WebKitWebResource* resource)
+ {
+ g_signal_handlers_disconnect_matched(resource, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ if (++m_resourcesLoaded == m_resourcesToLoad)
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ virtual void resourceFailed(WebKitWebResource* resource, GError* error)
+ {
+ g_assert_not_reached();
+ }
+
+ void waitUntilResourcesLoaded(size_t resourcesCount)
+ {
+ m_resourcesLoaded = 0;
+ m_resourcesToLoad = resourcesCount;
+ g_main_loop_run(m_mainLoop);
+ }
+
+ static void resourceGetDataCallback(GObject* object, GAsyncResult* result, gpointer userData)
+ {
+ size_t dataSize;
+ GOwnPtr<GError> error;
+ unsigned char* data = webkit_web_resource_get_data_finish(WEBKIT_WEB_RESOURCE(object), result, &dataSize, &error.outPtr());
+ g_assert(!error.get());
+ g_assert(data);
+ g_assert_cmpint(dataSize, >, 0);
+
+ ResourcesTest* test = static_cast<ResourcesTest*>(userData);
+ test->m_resourceData.set(reinterpret_cast<char*>(data));
+ test->m_resourceDataSize = dataSize;
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ void checkResourceData(WebKitWebResource* resource)
+ {
+ m_resourceDataSize = 0;
+ webkit_web_resource_get_data(resource, resourceGetDataCallback, this);
+ g_main_loop_run(m_mainLoop);
+
+ const char* uri = webkit_web_resource_get_uri(resource);
+ if (uri == kServer->getURIForPath("/")) {
+ g_assert_cmpint(m_resourceDataSize, ==, strlen(kIndexHtml));
+ g_assert(!strncmp(m_resourceData.get(), kIndexHtml, m_resourceDataSize));
+ } else if (uri == kServer->getURIForPath("/style.css")) {
+ g_assert_cmpint(m_resourceDataSize, ==, strlen(kStyleCSS));
+ g_assert(!strncmp(m_resourceData.get(), kStyleCSS, m_resourceDataSize));
+ } else if (uri == kServer->getURIForPath("/javascript.js")) {
+ g_assert_cmpint(m_resourceDataSize, ==, strlen(kJavascript));
+ g_assert(!strncmp(m_resourceData.get(), kJavascript, m_resourceDataSize));
+ } else
+ g_assert_not_reached();
+ m_resourceData.clear();
+ }
+
+ size_t m_resourcesLoaded;
+ size_t m_resourcesToLoad;
+ GOwnPtr<char> m_resourceData;
+ size_t m_resourceDataSize;
+};
+
+static void testWebViewResources(ResourcesTest* test, gconstpointer)
+{
+ // Nothing loaded yet, there shoulnd't be resources.
+ g_assert(!webkit_web_view_get_main_resource(test->m_webView));
+ g_assert(!webkit_web_view_get_subresources(test->m_webView));
+
+ // Load simple page without subresources.
+ test->loadHtml("<html><body>Testing WebKitGTK+</body></html>", 0);
+ test->waitUntilLoadFinished();
+ WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView);
+ g_assert(resource);
+ g_assert_cmpstr(webkit_web_view_get_uri(test->m_webView), ==, webkit_web_resource_get_uri(resource));
+ g_assert(!webkit_web_view_get_subresources(test->m_webView));
+
+ // Load simple page with subresources.
+ test->loadURI(kServer->getURIForPath("/").data());
+ test->waitUntilResourcesLoaded(4);
+
+ resource = webkit_web_view_get_main_resource(test->m_webView);
+ g_assert(resource);
+ g_assert_cmpstr(webkit_web_view_get_uri(test->m_webView), ==, webkit_web_resource_get_uri(resource));
+ GOwnPtr<GList> subresources(webkit_web_view_get_subresources(test->m_webView));
+ g_assert(subresources);
+ g_assert_cmpint(g_list_length(subresources.get()), ==, 3);
+
+#if 0
+ // Load the same URI again.
+ // FIXME: we need a workaround for bug https://bugs.webkit.org/show_bug.cgi?id=78510.
+ test->loadURI(kServer->getURIForPath("/").data());
+ test->waitUntilResourcesLoaded(4);
+#endif
+
+ // Reload.
+ webkit_web_view_reload(test->m_webView);
+ test->waitUntilResourcesLoaded(4);
+}
+
+class SingleResourceLoadTest: public ResourcesTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(SingleResourceLoadTest);
+
+ enum LoadEvents {
+ Started,
+ SentRequest,
+ Redirected,
+ ReceivedResponse,
+ ReceivedData,
+ Finished,
+ Failed
+ };
+
+ SingleResourceLoadTest()
+ : ResourcesTest()
+ , m_resourceDataReceived(0)
+ {
+ m_resourcesToLoad = 2;
+ }
+
+ void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request)
+ {
+ if (resource == webkit_web_view_get_main_resource(m_webView))
+ return;
+
+ m_resourceDataReceived = 0;
+ m_resource = resource;
+ m_loadEvents.append(Started);
+ }
+
+ void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+ {
+ if (resource != m_resource)
+ return;
+
+ if (redirectResponse)
+ m_loadEvents.append(Redirected);
+ else
+ m_loadEvents.append(SentRequest);
+ }
+
+ void resourceReceivedResponse(WebKitWebResource* resource)
+ {
+ if (resource != m_resource)
+ return;
+
+ m_loadEvents.append(ReceivedResponse);
+ }
+
+ void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived)
+ {
+ if (resource != m_resource)
+ return;
+
+ m_resourceDataReceived += bytesReceived;
+ if (!m_loadEvents.contains(ReceivedData))
+ m_loadEvents.append(ReceivedData);
+ }
+
+ void resourceFinished(WebKitWebResource* resource)
+ {
+ if (resource != m_resource) {
+ ResourcesTest::resourceFinished(resource);
+ return;
+ }
+
+ if (!m_loadEvents.contains(Failed)) {
+ WebKitURIResponse* response = webkit_web_resource_get_response(m_resource.get());
+ g_assert(response);
+ g_assert_cmpint(webkit_uri_response_get_content_length(response), ==, m_resourceDataReceived);
+ }
+ m_loadEvents.append(Finished);
+ ResourcesTest::resourceFinished(resource);
+ }
+
+ void resourceFailed(WebKitWebResource* resource, GError* error)
+ {
+ if (resource == m_resource)
+ m_loadEvents.append(Failed);
+ }
+
+ void waitUntilResourceLoadFinsihed()
+ {
+ m_resource = 0;
+ m_resourcesLoaded = 0;
+ g_main_loop_run(m_mainLoop);
+ }
+
+ int waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse()
+ {
+ waitUntilResourceLoadFinsihed();
+ g_assert(m_resource);
+ WebKitURIResponse* response = webkit_web_resource_get_response(m_resource.get());
+ g_assert(response);
+ return webkit_uri_response_get_status_code(response);
+ }
+
+ GRefPtr<WebKitWebResource> m_resource;
+ Vector<LoadEvents> m_loadEvents;
+ guint64 m_resourceDataReceived;
+};
+
+static void testWebResourceLoading(SingleResourceLoadTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/javascript.html").data());
+ test->waitUntilResourceLoadFinsihed();
+ g_assert(test->m_resource);
+ Vector<SingleResourceLoadTest::LoadEvents>& events = test->m_loadEvents;
+ g_assert_cmpint(events.size(), ==, 5);
+ g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started);
+ g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest);
+ g_assert_cmpint(events[2], ==, SingleResourceLoadTest::ReceivedResponse);
+ g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedData);
+ g_assert_cmpint(events[4], ==, SingleResourceLoadTest::Finished);
+ events.clear();
+
+ test->loadURI(kServer->getURIForPath("/redirected-css.html").data());
+ test->waitUntilResourceLoadFinsihed();
+ g_assert(test->m_resource);
+ g_assert_cmpint(events.size(), ==, 6);
+ g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started);
+ g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest);
+ g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Redirected);
+ g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedResponse);
+ g_assert_cmpint(events[4], ==, SingleResourceLoadTest::ReceivedData);
+ g_assert_cmpint(events[5], ==, SingleResourceLoadTest::Finished);
+ events.clear();
+
+ test->loadURI(kServer->getURIForPath("/invalid-css.html").data());
+ test->waitUntilResourceLoadFinsihed();
+ g_assert(test->m_resource);
+ g_assert_cmpint(events.size(), ==, 4);
+ g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started);
+ g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest);
+ g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Failed);
+ g_assert_cmpint(events[3], ==, SingleResourceLoadTest::Finished);
+ events.clear();
+}
+
+static void testWebResourceResponse(SingleResourceLoadTest* test, gconstpointer)
+{
+ // No cached resource: First load.
+ test->loadURI(kServer->getURIForPath("/javascript.html").data());
+ gint statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // No cached resource: Second load.
+ test->loadURI(kServer->getURIForPath("/javascript.html").data());
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // No cached resource: Reload.
+ webkit_web_view_reload(test->m_webView);
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // Cached resource: First load.
+ test->loadURI(kServer->getURIForPath("/image.html").data());
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // Cached resource: Second load.
+ test->loadURI(kServer->getURIForPath("/image.html").data());
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // Cached resource: Reload.
+ webkit_web_view_reload(test->m_webView);
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_NOT_MODIFIED);
+}
+
+class ResourceURITrackingTest: public SingleResourceLoadTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ResourceURITrackingTest);
+
+ ResourceURITrackingTest()
+ : SingleResourceLoadTest()
+ {
+ }
+
+ static void uriChanged(WebKitWebResource* resource, GParamSpec*, ResourceURITrackingTest* test)
+ {
+ g_assert(resource == test->m_resource.get());
+ g_assert_cmpstr(test->m_activeURI.data(), !=, webkit_web_resource_get_uri(test->m_resource.get()));
+ test->m_activeURI = webkit_web_resource_get_uri(test->m_resource.get());
+ }
+
+ void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request)
+ {
+ if (resource == webkit_web_view_get_main_resource(m_webView))
+ return;
+
+ m_resource = resource;
+ m_activeURI = webkit_web_resource_get_uri(resource);
+ checkActiveURI("/redirected.css");
+ g_assert_cmpstr(m_activeURI.data(), ==, webkit_uri_request_get_uri(request));
+ g_signal_connect(resource, "notify::uri", G_CALLBACK(uriChanged), this);
+ }
+
+ void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+ {
+ if (resource != m_resource)
+ return;
+
+ if (redirectResponse)
+ checkActiveURI("/simple-style.css");
+ else
+ checkActiveURI("/redirected.css");
+ g_assert_cmpstr(m_activeURI.data(), ==, webkit_uri_request_get_uri(request));
+ }
+
+ void resourceReceivedResponse(WebKitWebResource* resource)
+ {
+ if (resource != m_resource)
+ return;
+
+ checkActiveURI("/simple-style.css");
+ }
+
+ void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived)
+ {
+ }
+
+ void resourceFinished(WebKitWebResource* resource)
+ {
+ if (resource == m_resource)
+ checkActiveURI("/simple-style.css");
+ ResourcesTest::resourceFinished(resource);
+ }
+
+ void resourceFailed(WebKitWebResource*, GError*)
+ {
+ g_assert_not_reached();
+ }
+
+ CString m_activeURI;
+
+private:
+ void checkActiveURI(const char* uri)
+ {
+ // g_assert_cmpstr is a macro, so we need to cache the temporary string.
+ CString serverURI = kServer->getURIForPath(uri);
+ g_assert_cmpstr(m_activeURI.data(), ==, serverURI.data());
+ }
+};
+
+static void testWebResourceActiveURI(ResourceURITrackingTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/redirected-css.html").data());
+ test->waitUntilResourceLoadFinsihed();
+}
+
+static void testWebResourceGetData(ResourcesTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/").data());
+ // FIXME: this should be 4 instead of 3, but we don't get the css image resource
+ // due to bug https://bugs.webkit.org/show_bug.cgi?id=78510.
+ test->waitUntilResourcesLoaded(3);
+
+ WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView);
+ g_assert(resource);
+ test->checkResourceData(resource);
+
+ GOwnPtr<GList> subresources(webkit_web_view_get_subresources(test->m_webView));
+ for (GList* item = subresources.get(); item; item = g_list_next(item))
+ test->checkResourceData(WEBKIT_WEB_RESOURCE(item->data));
+}
+
+static void replacedContentResourceLoadStartedCallback()
+{
+ g_assert_not_reached();
+}
+
+static void testWebViewResourcesReplacedContent(ResourcesTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/").data());
+ // FIXME: this should be 4 instead of 3, but we don't get the css image resource
+ // due to bug https://bugs.webkit.org/show_bug.cgi?id=78510.
+ test->waitUntilResourcesLoaded(3);
+
+ static const char* replacedHtml =
+ "<html><head>"
+ " <title>Content Replaced</title>"
+ " <link rel='stylesheet' href='data:text/css,body { margin: 0px; padding: 0px; }' type='text/css'>"
+ " <script language='javascript' src='data:application/javascript,function foo () { var a = 1; }'></script>"
+ "</head><body onload='document.title=\"Loaded\"'>WebKitGTK+ resources on replaced content test</body></html>";
+ g_signal_connect(test->m_webView, "resource-load-started", G_CALLBACK(replacedContentResourceLoadStartedCallback), test);
+ test->replaceContent(replacedHtml, "http://error-page.foo", 0);
+ test->waitUntilTitleChangedTo("Loaded");
+
+ g_assert(!webkit_web_view_get_main_resource(test->m_webView));
+ g_assert(!webkit_web_view_get_subresources(test->m_webView));
+}
+
+static void addCacheHTTPHeadersToResponse(SoupMessage* message)
+{
+ // The actual date doesn't really matter.
+ SoupDate* soupDate = soup_date_new_from_now(0);
+ GOwnPtr<char> date(soup_date_to_string(soupDate, SOUP_DATE_HTTP));
+ soup_message_headers_append(message->response_headers, "Last-Modified", date.get());
+ soup_date_free(soupDate);
+ soup_message_headers_append(message->response_headers, "Cache-control", "public, max-age=31536000");
+ soupDate = soup_date_new_from_now(3600);
+ date.set(soup_date_to_string(soupDate, SOUP_DATE_HTTP));
+ soup_message_headers_append(message->response_headers, "Expires", date.get());
+ soup_date_free(soupDate);
+}
+
+static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
+{
+ if (message->method != SOUP_METHOD_GET) {
+ soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ soup_message_set_status(message, SOUP_STATUS_OK);
+
+ if (soup_message_headers_get(message->request_headers, "If-Modified-Since")) {
+ soup_message_set_status(message, SOUP_STATUS_NOT_MODIFIED);
+ soup_message_body_complete(message->response_body);
+ return;
+ }
+
+ if (g_str_equal(path, "/")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kIndexHtml, strlen(kIndexHtml));
+ } else if (g_str_equal(path, "/javascript.html")) {
+ static const char* javascriptHtml = "<html><head><script language='javascript' src='/javascript.js'></script></head><body></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, javascriptHtml, strlen(javascriptHtml));
+ } else if (g_str_equal(path, "/image.html")) {
+ static const char* imageHTML = "<html><body><img src='/blank.ico'></img></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, imageHTML, strlen(imageHTML));
+ } else if (g_str_equal(path, "/redirected-css.html")) {
+ static const char* redirectedCSSHtml = "<html><head><link rel='stylesheet' href='/redirected.css' type='text/css'></head><body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, redirectedCSSHtml, strlen(redirectedCSSHtml));
+ } else if (g_str_equal(path, "/invalid-css.html")) {
+ static const char* invalidCSSHtml = "<html><head><link rel='stylesheet' href='/invalid.css' type='text/css'></head><body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, invalidCSSHtml, strlen(invalidCSSHtml));
+ } else if (g_str_equal(path, "/style.css")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kStyleCSS, strlen(kStyleCSS));
+ addCacheHTTPHeadersToResponse(message);
+ } else if (g_str_equal(path, "/javascript.js")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kJavascript, strlen(kJavascript));
+ } else if (g_str_equal(path, "/blank.ico")) {
+ GOwnPtr<char> filePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), path, NULL));
+ char* contents;
+ gsize contentsLength;
+ g_file_get_contents(filePath.get(), &contents, &contentsLength, 0);
+ soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, contentsLength);
+ addCacheHTTPHeadersToResponse(message);
+ } else if (g_str_equal(path, "/simple-style.css")) {
+ static const char* simpleCSS =
+ "body {"
+ " margin: 0px;"
+ " padding: 0px;"
+ "}";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, simpleCSS, strlen(simpleCSS));
+ } else if (g_str_equal(path, "/redirected.css")) {
+ soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
+ soup_message_headers_append(message->response_headers, "Location", "/simple-style.css");
+ } else if (g_str_equal(path, "/invalid.css"))
+ soup_message_set_status(message, SOUP_STATUS_CANT_CONNECT);
+ soup_message_body_complete(message->response_body);
+}
+
+void beforeAll()
+{
+ kServer = new WebKitTestServer();
+ kServer->run(serverCallback);
+
+ ResourcesTest::add("WebKitWebView", "resources", testWebViewResources);
+ SingleResourceLoadTest::add("WebKitWebResource", "loading", testWebResourceLoading);
+ SingleResourceLoadTest::add("WebKitWebResource", "response", testWebResourceResponse);
+ ResourceURITrackingTest::add("WebKitWebResource", "active-uri", testWebResourceActiveURI);
+ ResourcesTest::add("WebKitWebResource", "get-data", testWebResourceGetData);
+ ResourcesTest::add("WebKitWebView", "replaced-content", testWebViewResourcesReplacedContent);
+}
+
+void afterAll()
+{
+ delete kServer;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
index 03c5f2fe8..19491c201 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "TestMain.h"
-#include <JavaScriptCore/GRefPtr.h>
#include <gtk/gtk.h>
#include <webkit2/webkit2.h>
+#include <wtf/gobject/GRefPtr.h>
static void testWebKitSettings(Test*, gconstpointer)
{
@@ -204,6 +204,11 @@ static void testWebKitSettings(Test*, gconstpointer)
webkit_settings_set_zoom_text_only(settings, TRUE);
g_assert(webkit_settings_get_zoom_text_only(settings));
+ // By default, JavaScript cannot access the clipboard.
+ g_assert(!webkit_settings_get_javascript_can_access_clipboard(settings));
+ webkit_settings_set_javascript_can_access_clipboard(settings, TRUE);
+ g_assert(webkit_settings_get_javascript_can_access_clipboard(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 bfeda169f..d65e8a641 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
@@ -332,6 +332,14 @@ static void testWebViewCreateReadyClose(UIClientTest* test, gconstpointer)
g_assert_cmpint(events[2], ==, UIClientTest::Close);
}
+static gboolean checkMimeTypeForFilter(GtkFileFilter* filter, const gchar* mimeType)
+{
+ GtkFileFilterInfo filterInfo;
+ filterInfo.contains = GTK_FILE_FILTER_MIME_TYPE;
+ filterInfo.mime_type = mimeType;
+ return gtk_file_filter_filter(filter, &filterInfo);
+}
+
static void testWebViewJavaScriptDialogs(UIClientTest* test, gconstpointer)
{
static const char* htmlOnLoadFormat = "<html><body onLoad=\"%s\"></body></html>";
@@ -452,6 +460,252 @@ static void testWebViewZoomLevel(WebViewTest* test, gconstpointer)
g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5);
}
+static void testWebViewRunJavaScript(WebViewTest* test, gconstpointer)
+{
+ static const char* html = "<html><body><a id='WebKitLink' href='http://www.webkitgtk.org/' title='WebKitGTK+ Title'>WebKitGTK+ Website</a></body></html>";
+ test->loadHtml(html, 0);
+ test->waitUntilLoadFinished();
+
+ GOwnPtr<GError> error;
+ WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').title;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ GOwnPtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Title");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').href;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ valueString.set(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "http://www.webkitgtk.org/");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').textContent", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ valueString.set(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Website");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 25;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 25);
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 2.5;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 2.5);
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = true", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultToBoolean(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = false", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(!WebViewTest::javascriptResultToBoolean(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = null", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultIsNull(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("function Foo() { a = 25; } Foo();", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultIsUndefined(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("foo();", &error.outPtr());
+ g_assert(!javascriptResult);
+ g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
+}
+
+class FileChooserTest: public UIClientTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(FileChooserTest);
+
+ FileChooserTest()
+ {
+ g_signal_connect(m_webView, "run-file-chooser", G_CALLBACK(runFileChooserCallback), this);
+ }
+
+ static gboolean runFileChooserCallback(WebKitWebView*, WebKitFileChooserRequest* request, FileChooserTest* test)
+ {
+ test->runFileChooser(request);
+ return TRUE;
+ }
+
+ void runFileChooser(WebKitFileChooserRequest* request)
+ {
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ m_fileChooserRequest = request;
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ WebKitFileChooserRequest* clickMouseButtonAndWaitForFileChooserRequest(int x, int y)
+ {
+ clickMouseButton(x, y);
+ g_main_loop_run(m_mainLoop);
+ return m_fileChooserRequest.get();
+ }
+
+private:
+ GRefPtr<WebKitFileChooserRequest> m_fileChooserRequest;
+};
+
+static void testWebViewFileChooserRequest(FileChooserTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+ static const char* fileChooserHTMLFormat = "<html><body><input style='position:absolute;left:0;top:0;margin:0;padding:0' type='file' %s/></body></html>";
+
+ // Multiple selections not allowed, no MIME filtering.
+ GOwnPtr<char> simpleFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, ""));
+ test->loadHtml(simpleFileUploadHTML.get(), 0);
+ test->waitUntilLoadFinished();
+ WebKitFileChooserRequest* fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ g_assert(!webkit_file_chooser_request_get_select_multiple(fileChooserRequest));
+
+ const gchar* const* mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest);
+ g_assert(!mimeTypes);
+ GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest);
+ g_assert(!filter);
+ const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(!selectedFiles);
+ webkit_file_chooser_request_cancel(fileChooserRequest);
+
+ // Multiple selections allowed, no MIME filtering, some pre-selected files.
+ GOwnPtr<char> multipleSelectionFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "multiple"));
+ test->loadHtml(multipleSelectionFileUploadHTML.get(), 0);
+ test->waitUntilLoadFinished();
+ fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ g_assert(webkit_file_chooser_request_get_select_multiple(fileChooserRequest));
+
+ mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest);
+ g_assert(!mimeTypes);
+ filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest);
+ g_assert(!filter);
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(!selectedFiles);
+
+ // Select some files.
+ const gchar* filesToSelect[4] = { "/foo", "/foo/bar", "/foo/bar/baz", 0 };
+ webkit_file_chooser_request_select_files(fileChooserRequest, filesToSelect);
+
+ // Check the files that have been just selected.
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(selectedFiles);
+ g_assert_cmpstr(selectedFiles[0], ==, "/foo");
+ g_assert_cmpstr(selectedFiles[1], ==, "/foo/bar");
+ g_assert_cmpstr(selectedFiles[2], ==, "/foo/bar/baz");
+ g_assert(!selectedFiles[3]);
+
+ // Perform another request to check if the list of files selected
+ // in the previous step appears now as part of the new request.
+ fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(selectedFiles);
+ g_assert_cmpstr(selectedFiles[0], ==, "/foo");
+ g_assert_cmpstr(selectedFiles[1], ==, "/foo/bar");
+ g_assert_cmpstr(selectedFiles[2], ==, "/foo/bar/baz");
+ g_assert(!selectedFiles[3]);
+ webkit_file_chooser_request_cancel(fileChooserRequest);
+
+ // Multiple selections not allowed, only accept images, audio and video files..
+ GOwnPtr<char> mimeFilteredFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "accept='audio/*,video/*,image/*'"));
+ test->loadHtml(mimeFilteredFileUploadHTML.get(), 0);
+ test->waitUntilLoadFinished();
+ fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ g_assert(!webkit_file_chooser_request_get_select_multiple(fileChooserRequest));
+
+ mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest);
+ g_assert(mimeTypes);
+ g_assert_cmpstr(mimeTypes[0], ==, "audio/*");
+ g_assert_cmpstr(mimeTypes[1], ==, "video/*");
+ g_assert_cmpstr(mimeTypes[2], ==, "image/*");
+ g_assert(!mimeTypes[3]);
+
+ filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest);
+ g_assert(GTK_IS_FILE_FILTER(filter));
+ g_assert(checkMimeTypeForFilter(filter, "audio/*"));
+ g_assert(checkMimeTypeForFilter(filter, "video/*"));
+ g_assert(checkMimeTypeForFilter(filter, "image/*"));
+
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(!selectedFiles);
+ webkit_file_chooser_request_cancel(fileChooserRequest);
+}
+
+class FullScreenClientTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(FullScreenClientTest);
+
+ enum FullScreenEvent {
+ None,
+ Enter,
+ Leave
+ };
+
+ static gboolean viewEnterFullScreenCallback(WebKitWebView*, FullScreenClientTest* test)
+ {
+ test->m_event = Enter;
+ g_main_loop_quit(test->m_mainLoop);
+ return FALSE;
+ }
+
+ static gboolean viewLeaveFullScreenCallback(WebKitWebView*, FullScreenClientTest* test)
+ {
+ test->m_event = Leave;
+ g_main_loop_quit(test->m_mainLoop);
+ return FALSE;
+ }
+
+ FullScreenClientTest()
+ : m_event(None)
+ {
+ webkit_settings_set_enable_fullscreen(webkit_web_view_get_settings(m_webView), TRUE);
+ g_signal_connect(m_webView, "enter-fullscreen", G_CALLBACK(viewEnterFullScreenCallback), this);
+ g_signal_connect(m_webView, "leave-fullscreen", G_CALLBACK(viewLeaveFullScreenCallback), this);
+ }
+
+ ~FullScreenClientTest()
+ {
+ g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ }
+
+ void requestFullScreenAndWaitUntilEnteredFullScreen()
+ {
+ m_event = None;
+ webkit_web_view_run_javascript(m_webView, "document.documentElement.webkitRequestFullScreen();", 0, 0);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ static gboolean leaveFullScreenIdle(FullScreenClientTest* test)
+ {
+ test->keyStroke(GDK_KEY_Escape);
+ return FALSE;
+ }
+
+ void leaveFullScreenAndWaitUntilLeftFullScreen()
+ {
+ m_event = None;
+ g_idle_add(reinterpret_cast<GSourceFunc>(leaveFullScreenIdle), this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ FullScreenEvent m_event;
+};
+
+static void testWebViewFullScreen(FullScreenClientTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml("<html><body>FullScreen test</body></html>", 0);
+ test->waitUntilLoadFinished();
+ test->requestFullScreenAndWaitUntilEnteredFullScreen();
+ g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Enter);
+ test->leaveFullScreenAndWaitUntilLeftFullScreen();
+ g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Leave);
+}
+
void beforeAll()
{
WebViewTest::add("WebKitWebView", "default-context", testWebViewDefaultContext);
@@ -463,6 +717,9 @@ void beforeAll()
UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties);
UIClientTest::add("WebKitWebView", "mouse-target", testWebViewMouseTarget);
WebViewTest::add("WebKitWebView", "zoom-level", testWebViewZoomLevel);
+ WebViewTest::add("WebKitWebView", "run-javascript", testWebViewRunJavaScript);
+ FileChooserTest::add("WebKitWebView", "file-chooser-request", testWebViewFileChooserRequest);
+ FullScreenClientTest::add("WebKitWebView", "fullscreen", testWebViewFullScreen);
}
void afterAll()
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
index 31de72911..7a9e49bc6 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
@@ -21,12 +21,14 @@
#include "config.h"
#include "WebViewTest.h"
+#include <JavaScriptCore/JSRetainPtr.h>
#include <WebCore/GOwnPtrGtk.h>
WebViewTest::WebViewTest()
: m_webView(WEBKIT_WEB_VIEW(g_object_ref_sink(webkit_web_view_new())))
, m_mainLoop(g_main_loop_new(0, TRUE))
, m_parentWindow(0)
+ , m_javascriptResult(0)
{
assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webView));
}
@@ -35,6 +37,8 @@ WebViewTest::~WebViewTest()
{
if (m_parentWindow)
gtk_widget_destroy(m_parentWindow);
+ if (m_javascriptResult)
+ webkit_javascript_result_unref(m_javascriptResult);
g_object_unref(m_webView);
g_main_loop_unref(m_mainLoop);
}
@@ -74,15 +78,7 @@ void WebViewTest::loadRequest(WebKitURIRequest* request)
void WebViewTest::replaceContent(const char* html, const char* contentURI, const char* baseURI)
{
- // FIXME: The active uri should be the contentURI,
- // but WebPageProxy doesn't return the unreachableURL
- // when the page has been loaded with AlternateHTML()
- // See https://bugs.webkit.org/show_bug.cgi?id=75465.
-#if 0
m_activeURI = contentURI;
-#else
- m_activeURI = "about:blank";
-#endif
webkit_web_view_replace_content(m_webView, html, contentURI, baseURI);
}
@@ -202,3 +198,142 @@ void WebViewTest::mouseMoveTo(int x, int y, unsigned int mouseModifiers)
gtk_main_do_event(event.get());
}
+void WebViewTest::clickMouseButton(int x, int y, unsigned int button, unsigned int mouseModifiers)
+{
+ doMouseButtonEvent(GDK_BUTTON_PRESS, x, y, button, mouseModifiers);
+ doMouseButtonEvent(GDK_BUTTON_RELEASE, x, y, button, mouseModifiers);
+}
+
+void WebViewTest::keyStroke(unsigned int keyVal, unsigned int keyModifiers)
+{
+ g_assert(m_parentWindow);
+ GtkWidget* viewWidget = GTK_WIDGET(m_webView);
+ g_assert(gtk_widget_get_realized(viewWidget));
+
+ GOwnPtr<GdkEvent> event(gdk_event_new(GDK_KEY_PRESS));
+ event->key.keyval = keyVal;
+
+ event->key.time = GDK_CURRENT_TIME;
+ event->key.window = gtk_widget_get_window(viewWidget);
+ g_object_ref(event->key.window);
+ gdk_event_set_device(event.get(), gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget))));
+ event->key.state = keyModifiers;
+
+ // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
+ GOwnPtr<GdkKeymapKey> keys;
+ int keysCount;
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount))
+ event->key.hardware_keycode = keys.get()[0].keycode;
+
+ gtk_main_do_event(event.get());
+ event->key.type = GDK_KEY_RELEASE;
+ gtk_main_do_event(event.get());
+}
+
+void WebViewTest::doMouseButtonEvent(GdkEventType eventType, int x, int y, unsigned int button, unsigned int mouseModifiers)
+{
+ g_assert(m_parentWindow);
+ GtkWidget* viewWidget = GTK_WIDGET(m_webView);
+ g_assert(gtk_widget_get_realized(viewWidget));
+
+ GOwnPtr<GdkEvent> event(gdk_event_new(eventType));
+ event->button.window = gtk_widget_get_window(viewWidget);
+ g_object_ref(event->button.window);
+
+ event->button.time = GDK_CURRENT_TIME;
+ event->button.x = x;
+ event->button.y = y;
+ event->button.axes = 0;
+ event->button.state = mouseModifiers;
+ event->button.button = button;
+
+ event->button.device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget)));
+
+ int xRoot, yRoot;
+ gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &xRoot, &yRoot);
+ event->button.x_root = xRoot;
+ event->button.y_root = yRoot;
+ gtk_main_do_event(event.get());
+}
+
+static void runJavaScriptReadyCallback(GObject*, GAsyncResult* result, WebViewTest* test)
+{
+ test->m_javascriptResult = webkit_web_view_run_javascript_finish(test->m_webView, result, test->m_javascriptError);
+ g_main_loop_quit(test->m_mainLoop);
+}
+
+WebKitJavascriptResult* WebViewTest::runJavaScriptAndWaitUntilFinished(const char* javascript, GError** error)
+{
+ if (m_javascriptResult)
+ webkit_javascript_result_unref(m_javascriptResult);
+ m_javascriptResult = 0;
+ m_javascriptError = error;
+ webkit_web_view_run_javascript(m_webView, javascript, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptReadyCallback), this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_javascriptResult;
+}
+
+static char* jsValueToCString(JSGlobalContextRef context, JSValueRef value)
+{
+ g_assert(value);
+ g_assert(JSValueIsString(context, value));
+
+ JSRetainPtr<JSStringRef> stringValue(Adopt, JSValueToStringCopy(context, value, 0));
+ g_assert(stringValue);
+
+ size_t cStringLength = JSStringGetMaximumUTF8CStringSize(stringValue.get());
+ char* cString = static_cast<char*>(g_malloc(cStringLength));
+ JSStringGetUTF8CString(stringValue.get(), cString, cStringLength);
+ return cString;
+}
+
+char* WebViewTest::javascriptResultToCString(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ return jsValueToCString(context, webkit_javascript_result_get_value(javascriptResult));
+}
+
+double WebViewTest::javascriptResultToNumber(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+ g_assert(JSValueIsNumber(context, value));
+
+ return JSValueToNumber(context, value, 0);
+}
+
+bool WebViewTest::javascriptResultToBoolean(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+ g_assert(JSValueIsBoolean(context, value));
+
+ return JSValueToBoolean(context, value);
+}
+
+bool WebViewTest::javascriptResultIsNull(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+
+ return JSValueIsNull(context, value);
+}
+
+bool WebViewTest::javascriptResultIsUndefined(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+
+ return JSValueIsUndefined(context, value);
+}
+
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
index 01f468562..92e123630 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
@@ -47,12 +47,28 @@ public:
void showInWindowAndWaitUntilMapped();
void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0);
+ void clickMouseButton(int x, int y, unsigned int button = 1, unsigned int mouseModifiers = 0);
+ void keyStroke(unsigned int keyVal, unsigned int keyModifiers = 0);
+
+ WebKitJavascriptResult* runJavaScriptAndWaitUntilFinished(const char* javascript, GError**);
+
+ // Javascript result helpers.
+ static char* javascriptResultToCString(WebKitJavascriptResult*);
+ static double javascriptResultToNumber(WebKitJavascriptResult*);
+ static bool javascriptResultToBoolean(WebKitJavascriptResult*);
+ static bool javascriptResultIsNull(WebKitJavascriptResult*);
+ static bool javascriptResultIsUndefined(WebKitJavascriptResult*);
WebKitWebView* m_webView;
GMainLoop* m_mainLoop;
CString m_activeURI;
GtkWidget* m_parentWindow;
CString m_expectedTitle;
+ WebKitJavascriptResult* m_javascriptResult;
+ GError** m_javascriptError;
+
+private:
+ void doMouseButtonEvent(GdkEventType, int, int, unsigned int, unsigned int);
};
#endif // WebViewTest_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h
index 0a807bc3d..c5460f333 100644
--- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h
+++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h
@@ -25,21 +25,25 @@
#include <webkit2/WebKitBackForwardList.h>
#include <webkit2/WebKitBackForwardListItem.h>
+#include <webkit2/WebKitCookieManager.h>
#include <webkit2/WebKitDefines.h>
#include <webkit2/WebKitDownload.h>
#include <webkit2/WebKitEditingCommands.h>
#include <webkit2/WebKitEnumTypes.h>
#include <webkit2/WebKitError.h>
+#include <webkit2/WebKitFileChooserRequest.h>
#include <webkit2/WebKitFindController.h>
#include <webkit2/WebKitHitTestResult.h>
+#include <webkit2/WebKitJavascriptResult.h>
#include <webkit2/WebKitPrintOperation.h>
#include <webkit2/WebKitScriptDialog.h>
#include <webkit2/WebKitSettings.h>
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitURIResponse.h>
#include <webkit2/WebKitWebContext.h>
-#include <webkit2/WebKitWebViewBase.h>
+#include <webkit2/WebKitWebResource.h>
#include <webkit2/WebKitWebView.h>
+#include <webkit2/WebKitWebViewBase.h>
#include <webkit2/WebKitWindowProperties.h>
#undef __WEBKIT2_H_INSIDE__
diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
index 5f7356039..de3032819 100644
--- a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
+++ b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
@@ -3,8 +3,10 @@ BOOLEAN:ENUM,STRING,POINTER
BOOLEAN:OBJECT
BOOLEAN:OBJECT,ENUM
BOOLEAN:STRING
+BOOLEAN:VOID
OBJECT:VOID
VOID:OBJECT,UINT
+VOID:OBJECT,OBJECT
VOID:OBJECT,POINTER
VOID:UINT64
diff --git a/Source/WebKit2/UIProcess/API/mac/PDFViewController.h b/Source/WebKit2/UIProcess/API/mac/PDFViewController.h
index 3a4f2f600..46aaf8458 100644
--- a/Source/WebKit2/UIProcess/API/mac/PDFViewController.h
+++ b/Source/WebKit2/UIProcess/API/mac/PDFViewController.h
@@ -62,6 +62,8 @@ public:
static Class pdfPreviewViewClass();
+ bool forwardScrollWheelEvent(NSEvent *);
+
NSPrintOperation *makePrintOperation(NSPrintInfo *);
void openPDFInFinder();
void savePDFToDownloadsFolder();
diff --git a/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm b/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm
index c5441a49f..91fcf34b2 100644
--- a/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm
+++ b/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm
@@ -36,6 +36,7 @@
#import "WebPreferences.h"
#import <PDFKit/PDFKit.h>
#import <WebCore/LocalizedStrings.h>
+#import <objc/runtime.h>
#import <wtf/text/CString.h>
#import <wtf/text/WTFString.h>
@@ -114,6 +115,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
- (PDFView *)pdfView;
- (void)setDocument:(PDFDocument *)pdfDocument;
+- (BOOL)forwardScrollWheelEvent:(NSEvent *)wheelEvent;
- (void)_applyPDFPreferences;
- (PDFSelection *)_nextMatchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag fromSelection:(PDFSelection *)initialSelection startInSelection:(BOOL)startInSelection;
@end
@@ -383,6 +385,11 @@ static void insertOpenWithDefaultPDFMenuItem(NSMenu *menu, NSUInteger index)
_pdfViewController->print();
}
+- (BOOL)forwardScrollWheelEvent:(NSEvent *)wheelEvent
+{
+ return _pdfViewController->forwardScrollWheelEvent(wheelEvent);
+}
+
@end
namespace WebKit {
@@ -486,7 +493,54 @@ Class PDFViewController::pdfPreviewViewClass()
return pdfPreviewViewClass;
}
+
+bool PDFViewController::forwardScrollWheelEvent(NSEvent *wheelEvent)
+{
+ CGFloat deltaX = [wheelEvent deltaX];
+ if ((deltaX > 0 && !page()->canGoBack()) || (deltaX < 0 && !page()->canGoForward()))
+ return false;
+
+ [m_wkView scrollWheel:wheelEvent];
+ return true;
+}
+
+#ifndef BUILDING_ON_SNOW_LEOPARD
+static IMP oldPDFViewScrollView_scrollWheel;
+
+static WKPDFView *findEnclosingWKPDFView(NSView *view)
+{
+ for (NSView *superview = [view superview]; superview; superview = [superview superview]) {
+ if ([superview isKindOfClass:[WKPDFView class]])
+ return static_cast<WKPDFView *>(superview);
+ }
+
+ return nil;
+}
+
+static void PDFViewScrollView_scrollWheel(NSScrollView* self, SEL _cmd, NSEvent *wheelEvent)
+{
+ CGFloat deltaX = [wheelEvent deltaX];
+ CGFloat deltaY = [wheelEvent deltaY];
+
+ NSSize contentsSize = [[self documentView] bounds].size;
+ NSRect visibleRect = [self documentVisibleRect];
+
+ // We only want to forward the wheel events if the horizontal delta is non-zero,
+ // and only if we're pinned to either the left or right side.
+ // We also never want to forward momentum scroll events.
+ if ([wheelEvent momentumPhase] == NSEventPhaseNone && deltaX && fabsf(deltaY) < fabsf(deltaX)
+ && ((deltaX > 0 && visibleRect.origin.x <= 0) || (deltaX < 0 && contentsSize.width <= NSMaxX(visibleRect)))) {
+ if (WKPDFView *pdfView = findEnclosingWKPDFView(self)) {
+ if ([pdfView forwardScrollWheelEvent:wheelEvent])
+ return;
+ }
+ }
+
+ oldPDFViewScrollView_scrollWheel(self, _cmd, wheelEvent);
+}
+#endif
+
NSBundle* PDFViewController::pdfKitBundle()
{
static NSBundle *pdfKitBundle;
@@ -502,6 +556,14 @@ NSBundle* PDFViewController::pdfKitBundle()
pdfKitBundle = [NSBundle bundleWithPath:pdfKitPath];
if (![pdfKitBundle load])
LOG_ERROR("Couldn't load PDFKit.framework");
+
+#ifndef BUILDING_ON_SNOW_LEOPARD
+ if (Class pdfViewScrollViewClass = [pdfKitBundle classNamed:@"PDFViewScrollView"]) {
+ if (Method scrollWheel = class_getInstanceMethod(pdfViewScrollViewClass, @selector(scrollWheel:)))
+ oldPDFViewScrollView_scrollWheel = method_setImplementation(scrollWheel, reinterpret_cast<IMP>(PDFViewScrollView_scrollWheel));
+ }
+#endif
+
return pdfKitBundle;
}
diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h
index dbe947a39..a9d7a9fa9 100644
--- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h
+++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h
@@ -55,7 +55,7 @@ private:
virtual bool isViewFocused();
virtual bool isViewVisible();
virtual bool isViewInWindow();
- virtual LayerHostingMode layerHostingMode();
+ virtual LayerHostingMode viewLayerHostingMode() OVERRIDE;
virtual void processDidCrash();
virtual void pageClosed();
@@ -63,7 +63,7 @@ private:
virtual void toolTipChanged(const String& oldToolTip, const String& newToolTip);
virtual void setCursor(const WebCore::Cursor&);
virtual void setCursorHiddenUntilMouseMoves(bool);
- virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
+ virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&);
virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo);
virtual void clearAllEditCommands();
@@ -72,6 +72,8 @@ private:
virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<WebCore::KeypressCommand>&);
virtual bool executeSavedCommandBySelector(const String& selector);
virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag);
+ virtual void setPromisedData(const String& pasteboardName, PassRefPtr<WebCore::SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title,
+ const String& url, const String& visibleUrl, PassRefPtr<WebCore::SharedBuffer> archiveBuffer);
virtual void updateTextInputState(bool updateSecureInputState);
virtual void resetTextInputState();
@@ -118,10 +120,10 @@ private:
virtual void didPerformDictionaryLookup(const String&, double scaleFactor, const DictionaryPopupInfo&);
virtual void dismissDictionaryLookupPanel();
- virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings);
- virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel);
- virtual String dismissCorrectionPanelSoon(WebCore::ReasonForDismissingCorrectionPanel);
- virtual void recordAutocorrectionResponse(WebCore::EditorClient::AutocorrectionResponseType, const String& replacedString, const String& replacementString);
+ virtual void showCorrectionPanel(WebCore::AlternativeTextType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings);
+ virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingAlternativeText);
+ virtual String dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText);
+ virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponseType, const String& replacedString, const String& replacementString);
virtual void recommendedScrollbarStyleDidChange(int32_t newStyle);
diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm
index 71a1a5075..72ea3493e 100644
--- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm
+++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm
@@ -37,12 +37,15 @@
#import "WebContextMenuProxyMac.h"
#import "WebEditCommandProxy.h"
#import "WebPopupMenuProxyMac.h"
+#import <WebCore/BitmapImage.h>
#import <WebCore/Cursor.h>
#import <WebCore/FloatRect.h>
#import <WebCore/FoundationExtras.h>
#import <WebCore/GraphicsContext.h>
+#import <WebCore/Image.h>
#import <WebCore/KeyboardEvent.h>
#import <WebCore/NotImplemented.h>
+#import <WebCore/SharedBuffer.h>
#import <wtf/PassOwnPtr.h>
#import <wtf/text/CString.h>
#import <wtf/text/WTFString.h>
@@ -190,7 +193,7 @@ bool PageClientImpl::isViewInWindow()
return [m_wkView window];
}
-LayerHostingMode PageClientImpl::layerHostingMode()
+LayerHostingMode PageClientImpl::viewLayerHostingMode()
{
#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER)
if (![m_wkView window])
@@ -233,7 +236,7 @@ void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
[NSCursor setHiddenUntilMouseMoves:hiddenUntilMouseMoves];
}
-void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportArguments&)
+void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&)
{
}
@@ -278,6 +281,13 @@ void PageClientImpl::setDragImage(const IntPoint& clientPosition, PassRefPtr<Sha
[m_wkView _setDragImage:dragNSImage.get() at:clientPosition linkDrag:isLinkDrag];
}
+void PageClientImpl::setPromisedData(const String& pasteboardName, PassRefPtr<SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title, const String& url, const String& visibleUrl, PassRefPtr<SharedBuffer> archiveBuffer)
+{
+ RefPtr<Image> image = BitmapImage::create();
+ image->setData(imageBuffer.get(), true);
+ [m_wkView _setPromisedData:image.get() withFileName:filename withExtension:extension withTitle:title withURL:url withVisibleURL:visibleUrl withArchive:archiveBuffer.get() forPasteboard:pasteboardName];
+}
+
void PageClientImpl::updateTextInputState(bool updateSecureInputState)
{
[m_wkView _updateTextInputStateIncludingSecureInputState:updateSecureInputState];
@@ -453,7 +463,7 @@ void PageClientImpl::dismissDictionaryLookupPanel()
#endif
}
-void PageClientImpl::showCorrectionPanel(CorrectionPanelInfo::PanelType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
+void PageClientImpl::showCorrectionPanel(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
{
#if !defined(BUILDING_ON_SNOW_LEOPARD)
if (!isViewVisible() || !isViewInWindow())
@@ -462,14 +472,14 @@ void PageClientImpl::showCorrectionPanel(CorrectionPanelInfo::PanelType type, co
#endif
}
-void PageClientImpl::dismissCorrectionPanel(ReasonForDismissingCorrectionPanel reason)
+void PageClientImpl::dismissCorrectionPanel(ReasonForDismissingAlternativeText reason)
{
#if !defined(BUILDING_ON_SNOW_LEOPARD)
m_correctionPanel.dismiss(reason);
#endif
}
-String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingCorrectionPanel reason)
+String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText reason)
{
#if !defined(BUILDING_ON_SNOW_LEOPARD)
return m_correctionPanel.dismiss(reason);
@@ -478,10 +488,10 @@ String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingCo
#endif
}
-void PageClientImpl::recordAutocorrectionResponse(EditorClient::AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString)
+void PageClientImpl::recordAutocorrectionResponse(AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString)
{
#if !defined(BUILDING_ON_SNOW_LEOPARD)
- NSCorrectionResponse response = responseType == EditorClient::AutocorrectionReverted ? NSCorrectionResponseReverted : NSCorrectionResponseEdited;
+ NSCorrectionResponse response = responseType == AutocorrectionReverted ? NSCorrectionResponseReverted : NSCorrectionResponseEdited;
CorrectionPanel::recordAutocorrectionResponse(m_wkView, response, replacedString, replacementString);
#endif
}
diff --git a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm
index 13aefb82b..63c58895f 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm
+++ b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm
@@ -27,6 +27,7 @@
#import "WKPrintingView.h"
#import "Logging.h"
+#import "PDFKitImports.h"
#import "PrintInfo.h"
#import "WebData.h"
#import "WebPageProxy.h"
@@ -228,8 +229,8 @@ static void pageDidDrawToPDF(WKDataRef dataRef, WKErrorRef, void* untypedContext
ASSERT([view _isPrintingPreview]);
if (data) {
- pair<HashMap<WebCore::IntRect, Vector<uint8_t> >::iterator, bool> entry = view->_pagePreviews.add(iter->second, Vector<uint8_t>());
- entry.first->second.append(data->bytes(), data->size());
+ HashMap<WebCore::IntRect, Vector<uint8_t> >::AddResult entry = view->_pagePreviews.add(iter->second, Vector<uint8_t>());
+ entry.iterator->second.append(data->bytes(), data->size());
}
view->_expectedPreviewCallbacks.remove(context->callbackID);
bool receivedResponseToLatestRequest = view->_latestExpectedPreviewCallback == context->callbackID;
@@ -411,33 +412,6 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext)
return 0; // Invalid page number.
}
-static NSString *pdfKitFrameworkPath()
-{
- NSString *systemLibraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, NO) objectAtIndex:0];
- return [systemLibraryPath stringByAppendingPathComponent:@"Frameworks/Quartz.framework/Frameworks/PDFKit.framework"];
-}
-
-static Class classFromPDFKit(NSString *className)
-{
- static NSBundle *pdfKitBundle = [NSBundle bundleWithPath:pdfKitFrameworkPath()];
- [pdfKitBundle load];
- return [pdfKitBundle classNamed:className];
-}
-
-static Class pdfAnnotationLinkClass()
-{
- static Class pdfAnnotationLinkClass = classFromPDFKit(@"PDFAnnotationLink");
- ASSERT(pdfAnnotationLinkClass);
- return pdfAnnotationLinkClass;
-}
-
-static Class pdfDocumentClass()
-{
- static Class pdfDocumentClass = classFromPDFKit(@"PDFDocument");
- ASSERT(pdfDocumentClass);
- return pdfDocumentClass;
-}
-
- (void)_drawPDFDocument:(PDFDocument *)pdfDocument page:(unsigned)page atPoint:(NSPoint)point
{
if (!pdfDocument) {
diff --git a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm
index 8c69b08b6..2be0cfd3c 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm
+++ b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm
@@ -28,6 +28,23 @@
#import <WebKitSystemInterface.h>
+@interface WKTextInputView : NSTextView {
+}
+@end
+
+@implementation WKTextInputView
+
+- (NSArray *)validAttributesForMarkedText
+{
+ // Let TSM know that a bottom input window would be created for marked text.
+ NSArray *regularAttributes = [super validAttributesForMarkedText];
+ NSMutableArray *floatingWindowAttributes = [NSMutableArray arrayWithArray:regularAttributes];
+ [floatingWindowAttributes addObject:@"__NSUsesFloatingInputWindow"];
+ return floatingWindowAttributes;
+}
+
+@end
+
@interface WKTextInputPanel : NSPanel {
NSTextView *_inputTextView;
}
@@ -65,7 +82,7 @@
[self setFrame:frame display:NO];
- _inputTextView = [[NSTextView alloc] initWithFrame:[(NSView *)self.contentView frame]];
+ _inputTextView = [[WKTextInputView alloc] initWithFrame:[(NSView *)self.contentView frame]];
_inputTextView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable | NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin;
NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[(NSView *)self.contentView frame]];
@@ -91,6 +108,7 @@
*string = nil;
// Let TSM know that a bottom input window would be created for marked text.
+ // FIXME: Can be removed once we can rely on __NSUsesFloatingInputWindow (or a better API) being available everywhere.
EventRef carbonEvent = static_cast<EventRef>(const_cast<void*>([event eventRef]));
if (carbonEvent) {
Boolean ignorePAH = true;
diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm
index a326dd089..8cd3027a3 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKView.mm
+++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm
@@ -64,6 +64,7 @@
#import <WebCore/DragData.h>
#import <WebCore/DragSession.h>
#import <WebCore/FloatRect.h>
+#import <WebCore/Image.h>
#import <WebCore/IntRect.h>
#import <WebCore/KeyboardEvent.h>
#import <WebCore/LocalizedStrings.h>
@@ -71,7 +72,11 @@
#import <WebCore/PlatformScreen.h>
#import <WebCore/Region.h>
#import <WebCore/RunLoop.h>
+#import <WebCore/SharedBuffer.h>
+#import <WebCore/WebCoreNSStringExtras.h>
+#import <WebCore/FileSystem.h>
#import <WebKitSystemInterface.h>
+#import <sys/stat.h>
#import <wtf/RefPtr.h>
#import <wtf/RetainPtr.h>
@@ -92,10 +97,13 @@
@end
@interface NSWindow (WKNSWindowDetails)
+#if defined(BUILDING_ON_SNOW_LEOPARD)
- (NSRect)_growBoxRect;
- (id)_growBoxOwner;
- (void)_setShowOpaqueGrowBoxForOwner:(id)owner;
- (BOOL)_updateGrowBoxForWindowFrameChange;
+#endif
+
- (NSRect)_intersectBottomCornersWithRect:(NSRect)viewRect;
- (void)_maskRoundedBottomCorners:(NSRect)clipRect;
@end
@@ -169,7 +177,6 @@ struct WKViewInterpretKeyEventsParameters {
bool _inResignFirstResponder;
NSEvent *_mouseDownEvent;
BOOL _ignoringMouseDraggedEvents;
- BOOL _dragHasStarted;
id _flagsChangedEventMonitor;
#if ENABLE(GESTURE_EVENTS)
@@ -194,6 +201,9 @@ struct WKViewInterpretKeyEventsParameters {
// We use this flag to determine when we need to paint the background (white or clear)
// when the web process is unresponsive or takes too long to paint.
BOOL _windowHasValidBackingStore;
+ RefPtr<WebCore::Image> _promisedImage;
+ String _promisedFilename;
+ String _promisedURL;
}
@end
@@ -374,7 +384,6 @@ 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;
@@ -527,11 +536,17 @@ WEBCORE_COMMAND(yankAndSelect)
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types
{
- Vector<String> pasteboardTypes;
size_t numTypes = [types count];
- for (size_t i = 0; i < numTypes; ++i)
- pasteboardTypes.append([types objectAtIndex:i]);
- return _data->_page->writeSelectionToPasteboard([pasteboard name], pasteboardTypes);
+ [pasteboard declareTypes:types owner:nil];
+ for (size_t i = 0; i < numTypes; ++i) {
+ if ([[types objectAtIndex:i] isEqualTo:NSStringPboardType])
+ [pasteboard setString:_data->_page->stringSelectionForPasteboard() forType:NSStringPboardType];
+ else {
+ RefPtr<SharedBuffer> buffer = _data->_page->dataSelectionForPasteboard([types objectAtIndex:i]);
+ [pasteboard setData:buffer ? [buffer->createNSData() autorelease] : nil forType:[types objectAtIndex:i]];
+ }
+ }
+ return YES;
}
- (void)centerSelectionInVisibleArea:(id)sender
@@ -711,9 +726,9 @@ static void validateCommandCallback(WKStringRef commandName, bool isEnabled, int
return YES;
// Add this item to the vector of items for a given command that are awaiting validation.
- pair<ValidationMap::iterator, bool> addResult = _data->_validationMap.add(commandName, ValidationVector());
- addResult.first->second.append(item);
- if (addResult.second) {
+ ValidationMap::AddResult addResult = _data->_validationMap.add(commandName, ValidationVector());
+ addResult.iterator->second.append(item);
+ if (addResult.isNewEntry) {
// If we are not already awaiting validation for this command, start the asynchronous validation process.
// FIXME: Theoretically, there is a race here; when we get the answer it might be old, from a previous time
// we asked for the same command; there is no guarantee the answer is still valid.
@@ -1024,7 +1039,6 @@ NATIVE_EVENT_HANDLER(scrollWheel, Wheel)
{
[self _setMouseDownEvent:event];
_data->_ignoringMouseDraggedEvents = NO;
- _data->_dragHasStarted = NO;
[self mouseDownInternal:event];
}
@@ -1124,9 +1138,11 @@ static const short kIOHIDEventTypeScroll = 6;
// As in insertText:replacementRange:, we assume that the call comes from an input method if there is marked text.
bool isFromInputMethod = _data->_page->editorState().hasComposition;
- if (parameters && !isFromInputMethod)
- parameters->commands->append(KeypressCommand(NSStringFromSelector(selector)));
- else {
+ if (parameters && !isFromInputMethod) {
+ KeypressCommand command(NSStringFromSelector(selector));
+ parameters->commands->append(command);
+ _data->_page->registerKeypressCommandName(command.commandName);
+ } else {
// FIXME: Send the command to Editor synchronously and only send it along the
// responder chain if it's a selector that does not correspond to an editing command.
[super doCommandBySelector:selector];
@@ -1171,7 +1187,9 @@ static const short kIOHIDEventTypeScroll = 6;
// then we also execute it immediately, as there will be no other chance.
if (parameters && !isFromInputMethod) {
ASSERT(replacementRange.location == NSNotFound);
- parameters->commands->append(KeypressCommand("insertText:", text));
+ KeypressCommand command("insertText:", text);
+ parameters->commands->append(command);
+ _data->_page->registerKeypressCommandName(command.commandName);
return;
}
@@ -1264,10 +1282,8 @@ 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;
@@ -1678,6 +1694,23 @@ static bool maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard,
return true;
}
+static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, SandboxExtension::HandleArray& handles)
+{
+ NSArray *types = [pasteboard types];
+ if (![types containsObject:NSFilenamesPboardType])
+ return;
+
+ NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
+ handles.allocate([files count]);
+ for (unsigned i = 0; i < [files count]; i++) {
+ NSString *file = [files objectAtIndex:i];
+ if (![[NSFileManager defaultManager] fileExistsAtPath:file])
+ continue;
+ SandboxExtension::Handle handle;
+ SandboxExtension::createHandle(file, SandboxExtension::ReadOnly, handles[i]);
+ }
+}
+
- (BOOL)performDragOperation:(id <NSDraggingInfo>)draggingInfo
{
IntPoint client([self convertPoint:[draggingInfo draggingLocation] fromView:nil]);
@@ -1689,7 +1722,10 @@ static bool maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard,
if (createdExtension)
_data->_page->process()->willAcquireUniversalFileReadSandboxExtension();
- _data->_page->performDrag(&dragData, [[draggingInfo draggingPasteboard] name], sandboxExtensionHandle);
+ SandboxExtension::HandleArray sandboxExtensionForUpload;
+ createSandboxExtensionsForFileUpload([draggingInfo draggingPasteboard], sandboxExtensionForUpload);
+
+ _data->_page->performDrag(&dragData, [[draggingInfo draggingPasteboard] name], sandboxExtensionHandle, sandboxExtensionForUpload);
return YES;
}
@@ -1716,6 +1752,8 @@ static bool maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard,
_data->_page->updateWindowIsVisible([[self window] isVisible]);
}
+
+#if defined(BUILDING_ON_SNOW_LEOPARD)
- (BOOL)_ownsWindowGrowBox
{
NSWindow* window = [self window];
@@ -1764,6 +1802,7 @@ static bool maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard,
return ownsGrowBox;
}
+#endif
// FIXME: Use AppKit constants for these when they are available.
static NSString * const windowDidChangeBackingPropertiesNotification = @"NSWindowDidChangeBackingPropertiesNotification";
@@ -1821,9 +1860,11 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl
[self removeWindowObservers];
[self addWindowObserversForWindow:window];
-
+
+#if defined(BUILDING_ON_SNOW_LEOPARD)
if ([currentWindow _growBoxOwner] == self)
[currentWindow _setShowOpaqueGrowBoxForOwner:nil];
+#endif
}
- (void)viewDidMoveToWindow
@@ -1989,8 +2030,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
[self getRectsBeingDrawn:&rectsBeingDrawn count:&numRectsBeingDrawn];
for (NSInteger i = 0; i < numRectsBeingDrawn; ++i) {
Region unpaintedRegion;
- IntRect rect = enclosingIntRect(rectsBeingDrawn[i]);
- drawingArea->paint(context, rect, unpaintedRegion);
+ drawingArea->paint(context, enclosingIntRect(rectsBeingDrawn[i]), unpaintedRegion);
// If the window doesn't have a valid backing store, we need to fill the parts of the page that we
// didn't paint with the background color (white or clear), to avoid garbage in those areas.
@@ -2117,7 +2157,8 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved location:[[flagsChangedEvent window] convertScreenToBase:[NSEvent mouseLocation]]
modifierFlags:[flagsChangedEvent modifierFlags] timestamp:[flagsChangedEvent timestamp] windowNumber:[flagsChangedEvent windowNumber]
context:[flagsChangedEvent context] eventNumber:0 clickCount:0 pressure:0];
- [self mouseMoved:fakeEvent];
+ NativeWebMouseEvent webEvent(fakeEvent, self);
+ _data->_page->handleMouseEvent(webEvent);
}
- (NSInteger)conversationIdentifier
@@ -2167,8 +2208,10 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (PassOwnPtr<WebKit::DrawingAreaProxy>)_createDrawingAreaProxy
{
+#if ENABLE(THREADED_SCROLLING)
if ([self _shouldUseTiledDrawingArea])
return TiledCoreAnimationDrawingAreaProxy::create(_data->_page.get());
+#endif
return DrawingAreaProxyImpl::create(_data->_page.get());
}
@@ -2184,6 +2227,9 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (void)_processDidCrash
{
+ if (_data->_layerHostingView)
+ [self _exitAcceleratedCompositingMode];
+
[self _updateRemoteAccessibilityRegistration:NO];
}
@@ -2434,7 +2480,8 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
[CATransaction begin];
[CATransaction setDisableActions:YES];
- [self addSubview:_data->_layerHostingView.get()];
+
+ [self addSubview:_data->_layerHostingView.get() positioned:NSWindowBelow relativeTo:nil];
// Create a root layer that will back the NSView.
RetainPtr<CALayer> rootLayer(AdoptNS, [[CALayer alloc] init]);
@@ -2519,7 +2566,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
if (pageHasCustomRepresentation)
_data->_pdfViewController = PDFViewController::create(self);
-
+
if (pageHasCustomRepresentation != hadPDFView)
_data->_page->drawingArea()->pageCustomRepresentationChanged();
}
@@ -2565,12 +2612,6 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (void)_setDragImage:(NSImage *)image at:(NSPoint)clientPoint linkDrag:(BOOL)linkDrag
{
- // We need to prevent re-entering this call to avoid crashing in AppKit.
- // Given the asynchronous nature of WebKit2 this can now happen.
- if (_data->_dragHasStarted)
- return;
-
- _data->_dragHasStarted = YES;
IntSize size([image size]);
size.scale(1.0 / _data->_page->deviceScaleFactor());
[image setSize:size];
@@ -2585,7 +2626,121 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
source:self
slideBack:YES];
- _data->_dragHasStarted = NO;
+}
+
+static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension)
+{
+ NSString *extensionAsSuffix = [@"." stringByAppendingString:extension];
+ return hasCaseInsensitiveSuffix(filename, extensionAsSuffix) || (stringIsCaseInsensitiveEqualToString(extension, @"jpeg")
+ && hasCaseInsensitiveSuffix(filename, @".jpg"));
+}
+
+- (void)_setPromisedData:(WebCore::Image *)image withFileName:(NSString *)filename withExtension:(NSString *)extension withTitle:(NSString *)title withURL:(NSString *)url withVisibleURL:(NSString *)visibleUrl withArchive:(WebCore::SharedBuffer*) archiveBuffer forPasteboard:(NSString *)pasteboardName
+
+{
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:pasteboardName];
+ RetainPtr<NSMutableArray> types(AdoptNS, [[NSMutableArray alloc] initWithObjects:NSFilesPromisePboardType, nil]);
+
+ [types.get() addObjectsFromArray:archiveBuffer ? PasteboardTypes::forImagesWithArchive() : PasteboardTypes::forImages()];
+ [pasteboard declareTypes:types.get() owner:self];
+ if (!matchesExtensionOrEquivalent(filename, extension))
+ filename = [[filename stringByAppendingString:@"."] stringByAppendingString:extension];
+
+ [pasteboard setString:url forType:NSURLPboardType];
+ [pasteboard setString:visibleUrl forType:PasteboardTypes::WebURLPboardType];
+ [pasteboard setString:title forType:PasteboardTypes::WebURLNamePboardType];
+ [pasteboard setPropertyList:[NSArray arrayWithObjects:[NSArray arrayWithObject:url], [NSArray arrayWithObject:title], nil] forType:PasteboardTypes::WebURLsWithTitlesPboardType];
+ [pasteboard setPropertyList:[NSArray arrayWithObject:extension] forType:NSFilesPromisePboardType];
+
+ if (archiveBuffer)
+ [pasteboard setData:[archiveBuffer->createNSData() autorelease] forType:PasteboardTypes::WebArchivePboardType];
+
+ _data->_promisedImage = image;
+ _data->_promisedFilename = filename;
+ _data->_promisedURL = url;
+}
+
+- (void)pasteboardChangedOwner:(NSPasteboard *)pasteboard
+{
+ _data->_promisedImage = 0;
+ _data->_promisedFilename = "";
+ _data->_promisedURL = "";
+}
+
+- (void)pasteboard:(NSPasteboard *)pasteboard provideDataForType:(NSString *)type
+{
+ // FIXME: need to support NSRTFDPboardType
+
+ if ([type isEqual:NSTIFFPboardType] && _data->_promisedImage) {
+ [pasteboard setData:(NSData *)_data->_promisedImage->getTIFFRepresentation() forType:NSTIFFPboardType];
+ _data->_promisedImage = 0;
+ }
+}
+
+static BOOL fileExists(NSString *path)
+{
+ struct stat statBuffer;
+ return !lstat([path fileSystemRepresentation], &statBuffer);
+}
+
+static NSString *pathWithUniqueFilenameForPath(NSString *path)
+{
+ // "Fix" the filename of the path.
+ NSString *filename = filenameByFixingIllegalCharacters([path lastPathComponent]);
+ path = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:filename];
+
+ if (fileExists(path)) {
+ // Don't overwrite existing file by appending "-n", "-n.ext" or "-n.ext.ext" to the filename.
+ NSString *extensions = nil;
+ NSString *pathWithoutExtensions;
+ NSString *lastPathComponent = [path lastPathComponent];
+ NSRange periodRange = [lastPathComponent rangeOfString:@"."];
+
+ if (periodRange.location == NSNotFound) {
+ pathWithoutExtensions = path;
+ } else {
+ extensions = [lastPathComponent substringFromIndex:periodRange.location + 1];
+ lastPathComponent = [lastPathComponent substringToIndex:periodRange.location];
+ pathWithoutExtensions = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:lastPathComponent];
+ }
+
+ for (unsigned i = 1; ; i++) {
+ NSString *pathWithAppendedNumber = [NSString stringWithFormat:@"%@-%d", pathWithoutExtensions, i];
+ path = [extensions length] ? [pathWithAppendedNumber stringByAppendingPathExtension:extensions] : pathWithAppendedNumber;
+ if (!fileExists(path))
+ break;
+ }
+ }
+
+ return path;
+}
+
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
+{
+ RetainPtr<NSFileWrapper> wrapper;
+ RetainPtr<NSData> data;
+
+ if (_data->_promisedImage) {
+ data.adoptNS(_data->_promisedImage->data()->createNSData());
+ wrapper.adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data.get()]);
+ [wrapper.get() setPreferredFilename:_data->_promisedFilename];
+ }
+
+ if (!wrapper) {
+ LOG_ERROR("Failed to create image file.");
+ return nil;
+ }
+
+ // FIXME: Report an error if we fail to create a file.
+ NSString *path = [[dropDestination path] stringByAppendingPathComponent:[wrapper.get() preferredFilename]];
+ path = pathWithUniqueFilenameForPath(path);
+ if (![wrapper.get() writeToFile:path atomically:NO updateFilenames:YES])
+ LOG_ERROR("Failed to create image file via -[NSFileWrapper writeToFile:atomically:updateFilenames:]");
+
+ if (!_data->_promisedURL.isEmpty())
+ WebCore::setMetadataURL(_data->_promisedURL, "", String(path));
+
+ return [NSArray arrayWithObject:[path lastPathComponent]];
}
- (void)_updateSecureInputState
@@ -2643,10 +2798,17 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (void)_didChangeScrollbarsForMainFrame
{
+#if defined(BUILDING_ON_SNOW_LEOPARD)
[self _updateGrowBoxForWindowFrameChange];
+#endif
}
#if ENABLE(FULLSCREEN_API)
+- (BOOL)hasFullScreenWindowController
+{
+ return (bool)_data->_fullScreenWindowController;
+}
+
- (WKFullScreenWindowController*)fullScreenWindowController
{
if (!_data->_fullScreenWindowController) {
@@ -2700,7 +2862,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (void)handleCorrectionPanelResult:(NSString*)result
{
- _data->_page->handleCorrectionPanelResult(result);
+ _data->_page->handleAlternativeTextUIResult(result);
}
@end
@@ -2748,8 +2910,8 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
_data->_pageClient = PageClientImpl::create(self);
_data->_page = toImpl(contextRef)->createWebPage(_data->_pageClient.get(), toImpl(pageGroupRef));
- _data->_page->initializeWebPage();
_data->_page->setIntrinsicDeviceScaleFactor([self _intrinsicDeviceScaleFactor]);
+ _data->_page->initializeWebPage();
#if ENABLE(FULLSCREEN_API)
_data->_page->fullScreenManager()->setWebView(self);
#endif
@@ -2759,12 +2921,10 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
[self _registerDraggedTypes];
if ([self _shouldUseTiledDrawingArea]) {
- CALayer *layer = [CALayer layer];
- layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite);
- self.layer = layer;
-
- self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawNever;
self.wantsLayer = YES;
+
+ // Explicitly set the layer contents placement so AppKit will make sure that our layer has masksToBounds set to YES.
+ self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft;
}
WebContext::statistics().wkViewCount++;
@@ -2772,6 +2932,21 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
return self;
}
+#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION)
+- (BOOL)wantsUpdateLayer
+{
+ return [self _shouldUseTiledDrawingArea];
+}
+
+- (void)updateLayer
+{
+ self.layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite);
+
+ if (DrawingAreaProxy* drawingArea = _data->_page->drawingArea())
+ drawingArea->waitForPossibleGeometryUpdate();
+}
+#endif
+
- (WKPageRef)pageRef
{
return toAPI(_data->_page.get());
diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
index 83346d3f1..6b6eb6bf4 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
+++ b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
@@ -35,6 +35,8 @@ namespace CoreIPC {
namespace WebCore {
struct KeypressCommand;
+ class Image;
+ class SharedBuffer;
}
namespace WebKit {
@@ -78,6 +80,7 @@ namespace WebKit {
- (void)_findStringInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count;
- (void)_countStringMatchesInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count;
- (void)_setDragImage:(NSImage *)image at:(NSPoint)clientPoint linkDrag:(BOOL)linkDrag;
+- (void)_setPromisedData:(WebCore::Image *)image withFileName:(NSString *)filename withExtension:(NSString *)extension withTitle:(NSString *)title withURL:(NSString *)url withVisibleURL:(NSString *)visibleUrl withArchive:(WebCore::SharedBuffer*) archiveBuffer forPasteboard:(NSString *)pasteboardName;
- (void)_updateSecureInputState;
- (void)_updateTextInputStateIncludingSecureInputState:(BOOL)updateSecureInputState;
- (void)_resetTextInputState;
@@ -85,6 +88,7 @@ namespace WebKit {
- (void)_didChangeScrollbarsForMainFrame;
#if ENABLE(FULLSCREEN_API)
+- (BOOL)hasFullScreenWindowController;
- (WKFullScreenWindowController*)fullScreenWindowController;
- (void)closeFullScreenWindowController;
#endif
diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h
index 1007f3a78..4c32d0f1b 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h
@@ -29,7 +29,7 @@
#include <QNetworkAccessManager>
#include <QObject>
#include <QWeakPointer>
-#include <QtDeclarative/qdeclarativelist.h>
+#include <QtQml/qqmllist.h>
#include <QtQuick/qquickitem.h>
class QWEBKIT_EXPORT QQuickNetworkReply : public QObject {
diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h
index 7df66f569..69a2d48df 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h
@@ -22,10 +22,10 @@
#define qquicknetworkrequest_p_h
#include "QtNetworkRequestData.h"
-#include "RefPtr.h"
+#include "wtf/RefPtr.h"
#include "qwebkitglobal.h"
#include <QObject>
-#include <QtDeclarative/qdeclarativelist.h>
+#include <QtQml/qqmllist.h>
#include <QtQuick/qquickitem.h>
class QWEBKIT_EXPORT QQuickNetworkRequest : public QObject {
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
index 9293c972f..203c72b7e 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
@@ -23,18 +23,18 @@
#include "LayerTreeHostProxy.h"
#include "QtWebPageEventHandler.h"
+#include "QtWebPageSGNode.h"
#include "TransformationMatrix.h"
#include "WebLayerTreeRenderer.h"
+#include "WebPageProxy.h"
#include "qquickwebpage_p_p.h"
#include "qquickwebview_p.h"
-#include <QPolygonF>
#include <QtQuick/QQuickCanvas>
-#include <QtQuick/QSGGeometryNode>
-#include <QtQuick/QSGMaterial>
-#include <private/qsgrendernode_p.h>
+
+using namespace WebKit;
QQuickWebPage::QQuickWebPage(QQuickWebView* viewportItem)
- : QQuickItem(viewportItem)
+ : QQuickItem(viewportItem->contentItem())
, d(new QQuickWebPagePrivate(this, viewportItem))
{
setFlag(ItemHasContents);
@@ -66,98 +66,16 @@ void QQuickWebPagePrivate::initialize(WebKit::WebPageProxy* webPageProxy)
eventHandler.reset(new QtWebPageEventHandler(toAPI(webPageProxy), q, viewportItem));
}
-void QQuickWebPagePrivate::setDrawingAreaSize(const QSize& size)
+void QQuickWebPagePrivate::paint(QPainter* painter)
{
- DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
- if (!drawingArea)
+ if (!webPageProxy->drawingArea())
return;
- drawingArea->setSize(WebCore::IntSize(size), WebCore::IntSize());
-}
-void QQuickWebPagePrivate::paint(QPainter* painter)
-{
- if (webPageProxy->drawingArea())
- webPageProxy->drawingArea()->paintLayerTree(painter);
+ LayerTreeHostProxy* layerTreeHostProxy = webPageProxy->drawingArea()->layerTreeHostProxy();
+ if (layerTreeHostProxy->layerTreeRenderer())
+ layerTreeHostProxy->layerTreeRenderer()->paintToGraphicsContext(painter);
}
-struct PageProxyNode : public QSGRenderNode {
- PageProxyNode(PassRefPtr<WebLayerTreeRenderer> renderer)
- : m_renderer(renderer)
- , m_scale(1)
- {
- }
-
- virtual StateFlags changedStates()
- {
- return StateFlags(StencilState) | ColorState | BlendState;
- }
-
- virtual void render(const RenderState&)
- {
- 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()
- {
- layerTreeRenderer()->purgeGLResources();
- }
-
- 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 (!d->webPageProxy->drawingArea())
@@ -166,21 +84,16 @@ QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*)
LayerTreeHostProxy* layerTreeHostProxy = d->webPageProxy->drawingArea()->layerTreeHostProxy();
WebLayerTreeRenderer* renderer = layerTreeHostProxy->layerTreeRenderer();
- 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;
- }
-
- renderer->syncRemoteContent();
-
+ QtWebPageSGNode* node = static_cast<QtWebPageSGNode*>(oldNode);
if (!node)
- node = new PageProxyNode(renderer);
+ node = new QtWebPageSGNode();
+ node->setRenderer(renderer);
+ renderer->syncRemoteContent();
node->setScale(d->contentsScale);
+ QColor backgroundColor = d->webPageProxy->drawsTransparentBackground() ? Qt::transparent : Qt::white;
+ QRectF backgroundRect(QPointF(0, 0), d->contentsSize);
+ node->setBackground(backgroundRect, backgroundColor);
return node;
}
@@ -197,7 +110,6 @@ void QQuickWebPage::setContentsSize(const QSizeF& size)
d->contentsSize = size;
d->updateSize();
- d->setDrawingAreaSize(d->contentsSize.toSize());
}
const QSizeF& QQuickWebPage::contentsSize() const
@@ -234,6 +146,9 @@ void QQuickWebPagePrivate::updateSize()
QSizeF scaledSize = contentsSize * contentsScale;
q->setSize(scaledSize);
viewportItem->updateContentsSize(scaledSize);
+ DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
+ if (drawingArea && drawingArea->layerTreeHostProxy())
+ drawingArea->layerTreeHostProxy()->setContentsSize(WebCore::FloatSize(contentsSize.width(), contentsSize.height()));
}
QQuickWebPagePrivate::~QQuickWebPagePrivate()
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h
index 9d791ac25..3a112d62b 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h
@@ -28,9 +28,12 @@
class QQuickWebPagePrivate;
class QQuickWebView;
-class QtWebPageEventHandler;
class QWebPreferences;
+namespace WebKit {
+class QtWebPageEventHandler;
+}
+
class QWEBKIT_EXPORT QQuickWebPage : public QQuickItem {
Q_OBJECT
public:
@@ -45,7 +48,7 @@ public:
QTransform transformFromItem() const;
QTransform transformToItem() const;
- QtWebPageEventHandler* eventHandler() const;
+ WebKit::QtWebPageEventHandler* eventHandler() const;
protected:
virtual QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*);
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h
index b28174124..e4be37364 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h
@@ -27,9 +27,8 @@
namespace WebKit {
class WebPageProxy;
class QtViewportInteractionEngine;
-}
-
class QtWebPageEventHandler;
+}
class QQuickWebPagePrivate {
public:
@@ -37,15 +36,13 @@ public:
~QQuickWebPagePrivate();
void initialize(WebKit::WebPageProxy*);
- void setDrawingAreaSize(const QSize&);
void updateSize();
- void paintToCurrentGLContext(const QTransform&, float opacity, const QRectF& clipRect);
void paint(QPainter*);
void resetPaintNode();
- QScopedPointer<QtWebPageEventHandler> eventHandler;
+ QScopedPointer<WebKit::QtWebPageEventHandler> eventHandler;
QQuickWebPage* const q;
QQuickWebView* const viewportItem;
WebKit::WebPageProxy* webPageProxy;
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
index 6e518ff12..b1b465526 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
@@ -23,12 +23,19 @@
#include "DownloadProxy.h"
#include "DrawingAreaProxyImpl.h"
+#include "QtDialogRunner.h"
#include "QtDownloadManager.h"
+#include "QtViewportInteractionEngine.h"
#include "QtWebContext.h"
#include "QtWebIconDatabaseClient.h"
#include "QtWebPageEventHandler.h"
+#include "QtWebPageLoadClient.h"
+#include "QtWebPagePolicyClient.h"
#include "UtilsQt.h"
#include "WebBackForwardList.h"
+#if ENABLE(FULLSCREEN_API)
+#include "WebFullScreenManagerProxy.h"
+#endif
#include "WebPageGroup.h"
#include "WebPreferences.h"
@@ -45,18 +52,21 @@
#include "qwebviewportinfo_p.h"
#include <JavaScriptCore/InitializeThreading.h>
-#include <QDeclarativeEngine>
-#include <QFileDialog>
-#include <QtQuick/QQuickCanvas>
+#include <QDateTime>
#include <WebCore/IntPoint.h>
#include <WebCore/IntRect.h>
#include <WKOpenPanelResultListener.h>
#include <wtf/Assertions.h>
+#include <wtf/MainThread.h>
#include <wtf/text/WTFString.h>
using namespace WebCore;
+using namespace WebKit;
static bool s_flickableViewportEnabled = true;
+static const int kAxisLockSampleCount = 5;
+static const qreal kAxisLockVelocityThreshold = 300;
+static const qreal kAxisLockVelocityDirectionThreshold = 50;
static QQuickWebViewPrivate* createPrivateObject(QQuickWebView* publicObject)
{
@@ -65,9 +75,80 @@ static QQuickWebViewPrivate* createPrivateObject(QQuickWebView* publicObject)
return new QQuickWebViewLegacyPrivate(publicObject);
}
+QQuickWebViewPrivate::FlickableAxisLocker::FlickableAxisLocker()
+ : m_allowedDirection(QQuickFlickable::AutoFlickDirection)
+ , m_sampleCount(0)
+{
+}
+
+QVector2D QQuickWebViewPrivate::FlickableAxisLocker::touchVelocity(const QTouchEvent* event)
+{
+ static bool touchVelocityAvailable = event->device()->capabilities().testFlag(QTouchDevice::Velocity);
+ const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
+
+ if (touchVelocityAvailable)
+ return touchPoint.velocity();
+
+ const QLineF movementLine(touchPoint.screenPos(), m_initialScreenPosition);
+ const qint64 elapsed = m_time.elapsed();
+
+ if (!elapsed)
+ return QVector2D(0, 0);
+
+ // Calculate an approximate velocity vector in the unit of pixel / second.
+ return QVector2D(1000 * movementLine.dx() / elapsed, 1000 * movementLine.dy() / elapsed);
+}
+
+void QQuickWebViewPrivate::FlickableAxisLocker::update(const QTouchEvent* event)
+{
+ ASSERT(event->touchPoints().size() == 1);
+ const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
+
+ ++m_sampleCount;
+
+ if (m_sampleCount == 1) {
+ m_initialScreenPosition = touchPoint.screenPos();
+ m_time.restart();
+ return;
+ }
+
+ if (m_sampleCount > kAxisLockSampleCount
+ || m_allowedDirection == QQuickFlickable::HorizontalFlick
+ || m_allowedDirection == QQuickFlickable::VerticalFlick)
+ return;
+
+ QVector2D velocity = touchVelocity(event);
+
+ qreal directionIndicator = qAbs(velocity.x()) - qAbs(velocity.y());
+
+ if (velocity.length() > kAxisLockVelocityThreshold && qAbs(directionIndicator) > kAxisLockVelocityDirectionThreshold)
+ m_allowedDirection = (directionIndicator > 0) ? QQuickFlickable::HorizontalFlick : QQuickFlickable::VerticalFlick;
+}
+
+void QQuickWebViewPrivate::FlickableAxisLocker::setReferencePosition(const QPointF& position)
+{
+ m_lockReferencePosition = position;
+}
+
+void QQuickWebViewPrivate::FlickableAxisLocker::reset()
+{
+ m_allowedDirection = QQuickFlickable::AutoFlickDirection;
+ m_sampleCount = 0;
+}
+
+QPointF QQuickWebViewPrivate::FlickableAxisLocker::adjust(const QPointF& position)
+{
+ if (m_allowedDirection == QQuickFlickable::HorizontalFlick)
+ return QPointF(position.x(), m_lockReferencePosition.y());
+
+ if (m_allowedDirection == QQuickFlickable::VerticalFlick)
+ return QPointF(m_lockReferencePosition.x(), position.y());
+
+ return position;
+}
+
QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
: q_ptr(viewport)
- , flickProvider(0)
, alertDialog(0)
, confirmDialog(0)
, promptDialog(0)
@@ -75,14 +156,15 @@ QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
, certificateVerificationDialog(0)
, itemSelector(0)
, proxyAuthenticationDialog(0)
- , userDidOverrideContentWidth(false)
- , userDidOverrideContentHeight(false)
+ , filePicker(0)
+ , databaseQuotaDialog(0)
+ , m_useDefaultContentItemSize(true)
, m_navigatorQtObjectEnabled(false)
, m_renderToOffscreenBuffer(false)
- , m_loadStartedSignalSent(false)
- , m_dialogRunnerActive(false)
+ , m_dialogActive(false)
{
- viewport->setFlags(QQuickItem::ItemClipsChildrenToShape);
+ viewport->setClip(true);
+ viewport->setPixelAligned(true);
QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged()));
QObject::connect(viewport, SIGNAL(urlChanged()), viewport, SLOT(_q_onUrlChanged()));
pageView.reset(new QQuickWebPage(viewport));
@@ -104,6 +186,9 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa
context = contextRef ? QtWebContext::create(toImpl(contextRef)) : QtWebContext::defaultContext();
webPageProxy = context->createWebPage(&pageClient, pageGroup.get());
+#if ENABLE(FULLSCREEN_API)
+ webPageProxy->fullScreenManager()->setWebView(q_ptr);
+#endif
QQuickWebPagePrivate* const pageViewPrivate = pageView.data()->d;
pageViewPrivate->initialize(webPageProxy.get());
@@ -135,26 +220,16 @@ bool QQuickWebViewPrivate::transparentBackground() const
return webPageProxy->drawsTransparentBackground();
}
-void QQuickWebViewPrivate::enableMouseEvents()
-{
- Q_Q(QQuickWebView);
- q->setAcceptedMouseButtons(Qt::MouseButtonMask);
- q->setAcceptHoverEvents(true);
-}
-
-void QQuickWebViewPrivate::disableMouseEvents()
-{
- Q_Q(QQuickWebView);
- q->setAcceptedMouseButtons(Qt::NoButton);
- q->setAcceptHoverEvents(false);
-}
-
QPointF QQuickWebViewPrivate::pageItemPos()
{
ASSERT(pageView);
return pageView->pos();
}
+/*!
+ \qmlsignal WebView::loadingChanged(WebLoadRequest request)
+*/
+
void QQuickWebViewPrivate::loadDidSucceed()
{
Q_Q(QQuickWebView);
@@ -194,14 +269,6 @@ 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();
@@ -210,18 +277,18 @@ void QQuickWebViewPrivate::didChangeBackForwardList()
void QQuickWebViewPrivate::processDidCrash()
{
pageView->eventHandler()->resetGestureRecognizers();
+ pageLoadClient->completeLoadWhenProcessDidCrashIfNeeded();
+
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()
{
qWarning("WARNING: The web process has been successfully restarted.");
- pageView->d->setDrawingAreaSize(viewSize());
+
+ webPageProxy->drawingArea()->setSize(viewSize(), IntSize());
+ updateViewportSize();
}
PassOwnPtr<DrawingAreaProxy> QQuickWebViewPrivate::createDrawingAreaProxy()
@@ -365,59 +432,52 @@ void QQuickWebViewPrivate::execDialogRunner(QtDialogRunner& dialogRunner)
setViewInAttachedProperties(dialogRunner.dialog());
disableMouseEvents();
- m_dialogRunnerActive = true;
+ m_dialogActive = true;
dialogRunner.exec();
- m_dialogRunnerActive = false;
+ m_dialogActive = false;
enableMouseEvents();
}
void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type)
{
-#ifndef QT_NO_FILEDIALOG
Q_Q(QQuickWebView);
- openPanelResultListener = listenerRef;
-
- // Qt does not support multiple files suggestion, so we get just the first suggestion.
- QString selectedFileName;
- if (!selectedFileNames.isEmpty())
- selectedFileName = selectedFileNames.at(0);
- Q_ASSERT(!fileDialog);
+ if (!filePicker)
+ return;
- QWindow* window = q->canvas();
- if (!window)
+ QtDialogRunner dialogRunner;
+ if (!dialogRunner.initForFilePicker(filePicker, q, selectedFileNames, (type == QtWebPageUIClient::MultipleFilesSelection)))
return;
- fileDialog = new QFileDialog(0, QString(), selectedFileName);
- fileDialog->window()->winId(); // Ensure that the dialog has a window
- Q_ASSERT(fileDialog->window()->windowHandle());
- fileDialog->window()->windowHandle()->setTransientParent(window);
+ execDialogRunner(dialogRunner);
- fileDialog->open(q, SLOT(_q_onOpenPanelFilesSelected()));
+ if (dialogRunner.wasAccepted()) {
+ QStringList selectedPaths = dialogRunner.filePaths();
- q->connect(fileDialog, SIGNAL(finished(int)), SLOT(_q_onOpenPanelFinished(int)));
-#endif
-}
-
-void QQuickWebViewPrivate::_q_onOpenPanelFilesSelected()
-{
- const QStringList fileList = fileDialog->selectedFiles();
- Vector<RefPtr<APIObject> > wkFiles(fileList.size());
+ Vector<RefPtr<APIObject> > wkFiles(selectedPaths.size());
+ for (unsigned i = 0; i < selectedPaths.size(); ++i)
+ wkFiles[i] = WebURL::create(QUrl::fromLocalFile(selectedPaths.at(i)).toString());
- for (unsigned i = 0; i < fileList.size(); ++i)
- wkFiles[i] = WebURL::create(QUrl::fromLocalFile(fileList.at(i)).toString());
+ WKOpenPanelResultListenerChooseFiles(listenerRef, toAPI(ImmutableArray::adopt(wkFiles).leakRef()));
+ } else
+ WKOpenPanelResultListenerCancel(listenerRef);
- WKOpenPanelResultListenerChooseFiles(openPanelResultListener, toAPI(ImmutableArray::adopt(wkFiles).leakRef()));
}
-void QQuickWebViewPrivate::_q_onOpenPanelFinished(int result)
+quint64 QQuickWebViewPrivate::exceededDatabaseQuota(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
{
- if (result == QDialog::Rejected)
- WKOpenPanelResultListenerCancel(openPanelResultListener);
+ if (!databaseQuotaDialog)
+ return 0;
+
+ Q_Q(QQuickWebView);
+ QtDialogRunner dialogRunner;
+ if (!dialogRunner.initForDatabaseQuotaDialog(databaseQuotaDialog, q, databaseName, displayName, securityOrigin, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage))
+ return 0;
+
+ execDialogRunner(dialogRunner);
- fileDialog->deleteLater();
- fileDialog = 0;
+ return dialogRunner.wasAccepted() ? dialogRunner.databaseQuota() : 0;
}
void QQuickWebViewPrivate::setViewInAttachedProperties(QObject* object)
@@ -462,12 +522,27 @@ void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled)
context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled);
}
+QPointF QQuickWebViewPrivate::contentPos() const
+{
+ Q_Q(const QQuickWebView);
+ return QPointF(q->contentX(), q->contentY());
+}
+
+void QQuickWebViewPrivate::setContentPos(const QPointF& pos)
+{
+ Q_Q(QQuickWebView);
+ q->setContentX(pos.x());
+ q->setContentY(pos.y());
+}
+
QRect QQuickWebViewPrivate::visibleContentsRect() const
{
Q_Q(const QQuickWebView);
const QRectF visibleRect(q->boundingRect().intersected(pageView->boundingRect()));
- return q->mapRectToWebContent(visibleRect).toAlignedRect();
+ // We avoid using toAlignedRect() because it produces inconsistent width and height.
+ QRectF mappedRect(q->mapRectToWebContent(visibleRect));
+ return QRect(floor(mappedRect.x()), floor(mappedRect.y()), floor(mappedRect.width()), floor(mappedRect.height()));
}
WebCore::IntSize QQuickWebViewPrivate::viewSize() const
@@ -475,6 +550,15 @@ WebCore::IntSize QQuickWebViewPrivate::viewSize() const
return WebCore::IntSize(pageView->width(), pageView->height());
}
+/*!
+ \internal
+
+ \qmlsignal WebViewExperimental::onMessageReceived(var message)
+
+ \brief Emitted when JavaScript code executing on the web page calls navigator.qt.postMessage().
+
+ \sa postMessage
+*/
void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String& message)
{
QVariantMap variantMap;
@@ -486,6 +570,12 @@ void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String&
QQuickWebViewLegacyPrivate::QQuickWebViewLegacyPrivate(QQuickWebView* viewport)
: QQuickWebViewPrivate(viewport)
{
+ // Default values for the Legacy view.
+ attributes.devicePixelRatio = 1;
+ attributes.initialScale = 1;
+ attributes.minimumScale = 1;
+ attributes.maximumScale = 1;
+ attributes.userScalable = 0;
}
void QQuickWebViewLegacyPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
@@ -505,16 +595,46 @@ void QQuickWebViewLegacyPrivate::updateViewportSize()
// The fixed layout is handled by the FrameView and the drawing area doesn't behave differently
// whether its fixed or not. We still need to tell the drawing area which part of it
// has to be rendered on tiles, and in desktop mode it's all of it.
- webPageProxy->drawingArea()->setVisibleContentsRectForScaling(IntRect(IntPoint(), viewportSize), 1);
+ webPageProxy->drawingArea()->setSize(viewportSize, IntSize());
+ webPageProxy->drawingArea()->setVisibleContentsRect(IntRect(IntPoint(), viewportSize), 1, FloatPoint());
+}
+
+void QQuickWebViewLegacyPrivate::enableMouseEvents()
+{
+ Q_Q(QQuickWebView);
+ q->setAcceptedMouseButtons(Qt::MouseButtonMask);
+ q->setAcceptHoverEvents(true);
+}
+
+void QQuickWebViewLegacyPrivate::disableMouseEvents()
+{
+ Q_Q(QQuickWebView);
+ q->setAcceptedMouseButtons(Qt::NoButton);
+ q->setAcceptHoverEvents(false);
+}
+
+qreal QQuickWebViewLegacyPrivate::zoomFactor() const
+{
+ return webPageProxy->pageZoomFactor();
+}
+
+void QQuickWebViewLegacyPrivate::setZoomFactor(qreal factor)
+{
+ webPageProxy->setPageZoomFactor(factor);
}
QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport)
: QQuickWebViewPrivate(viewport)
- , postTransitionState(adoptPtr(new PostTransitionState(this)))
- , isTransitioningToNewPage(false)
, pageIsSuspended(true)
, loadSuccessDispatchIsPending(false)
{
+ // Disable mouse events on the flickable web view so we do not
+ // select text during pan gestures on platforms which send both
+ // touch and mouse events simultaneously.
+ // FIXME: Temporary workaround code which should be removed when
+ // bug http://codereview.qt-project.org/21896 is fixed.
+ viewport->setAcceptedMouseButtons(Qt::NoButton);
+ viewport->setAcceptHoverEvents(false);
}
QQuickWebViewFlickablePrivate::~QQuickWebViewFlickablePrivate()
@@ -530,50 +650,42 @@ void QQuickWebViewFlickablePrivate::initialize(WKContextRef contextRef, WKPageGr
QPointF QQuickWebViewFlickablePrivate::pageItemPos()
{
+ Q_Q(QQuickWebView);
// Flickable moves its contentItem so we need to take that position into account,
// as well as the potential displacement of the page on the contentItem because
// of additional QML items.
- qreal xPos = flickProvider->contentItem()->x() + pageView->x();
- qreal yPos = flickProvider->contentItem()->y() + pageView->y();
+ qreal xPos = q->contentItem()->x() + pageView->x();
+ qreal yPos = q->contentItem()->y() + pageView->y();
return QPointF(xPos, yPos);
}
void QQuickWebViewFlickablePrivate::updateContentsSize(const QSizeF& size)
{
- ASSERT(flickProvider);
+ Q_Q(QQuickWebView);
// Make sure that the contentItem is sized to the page
// if the user did not add other flickable items in QML.
// If the user adds items in QML he has to make sure to
- // also bind the contentWidth and contentHeight accordingly.
+ // disable the default content item size property on the WebView
+ // and bind the contentWidth and contentHeight accordingly.
// This is in accordance with normal QML Flickable behaviour.
- if (!userDidOverrideContentWidth)
- flickProvider->setContentWidth(size.width());
- if (!userDidOverrideContentHeight)
- flickProvider->setContentHeight(size.height());
+ if (!m_useDefaultContentItemSize)
+ return;
+
+ q->setContentWidth(size.width());
+ q->setContentHeight(size.height());
}
void QQuickWebViewFlickablePrivate::onComponentComplete()
{
Q_Q(QQuickWebView);
- ASSERT(!flickProvider);
- flickProvider = new QtFlickProvider(q, pageView.data());
-
- // Propagate flickable signals.
- const QQuickWebViewExperimental* experimental = q->experimental();
- QObject::connect(flickProvider, SIGNAL(contentWidthChanged()), experimental, SIGNAL(contentWidthChanged()));
- QObject::connect(flickProvider, SIGNAL(contentHeightChanged()), experimental, SIGNAL(contentHeightChanged()));
- QObject::connect(flickProvider, SIGNAL(contentXChanged()), experimental, SIGNAL(contentXChanged()));
- QObject::connect(flickProvider, SIGNAL(contentYChanged()), experimental, SIGNAL(contentYChanged()));
-
- interactionEngine.reset(new QtViewportInteractionEngine(q, pageView.data(), flickProvider));
+ interactionEngine.reset(new QtViewportInteractionEngine(q, pageView.data()));
pageView->eventHandler()->setViewportInteractionEngine(interactionEngine.data());
QObject::connect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), q, SLOT(_q_suspend()));
QObject::connect(interactionEngine.data(), SIGNAL(contentResumeRequested()), q, SLOT(_q_resume()));
- QObject::connect(interactionEngine.data(), SIGNAL(contentWasMoved(const QPointF&)), q, SLOT(_q_commitPositionChange(const QPointF&)));
- QObject::connect(interactionEngine.data(), SIGNAL(contentWasScaled()), q, SLOT(_q_commitScaleChange()));
+ QObject::connect(interactionEngine.data(), SIGNAL(contentViewportChanged(QPointF)), q, SLOT(_q_contentViewportChanged(QPointF)));
_q_resume();
@@ -594,33 +706,47 @@ void QQuickWebViewFlickablePrivate::loadDidSucceed()
QQuickWebViewPrivate::loadDidSucceed();
else
loadSuccessDispatchIsPending = true;
-
}
void QQuickWebViewFlickablePrivate::loadDidCommit()
{
// Due to entering provisional load before committing, we
// might actually be suspended here.
-
- isTransitioningToNewPage = true;
}
void QQuickWebViewFlickablePrivate::didFinishFirstNonEmptyLayout()
{
- if (!pageIsSuspended) {
- isTransitioningToNewPage = false;
- postTransitionState->apply();
- }
}
-void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args)
+void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportAttributes& newAttributes)
{
- viewportArguments = args;
+ Q_Q(QQuickWebView);
- if (isTransitioningToNewPage)
- return;
+ QSize viewportSize = q->boundingRect().size().toSize();
+
+ // FIXME: Revise these when implementing fit-to-width.
+ WebCore::ViewportAttributes attr = newAttributes;
+ WebCore::restrictMinimumScaleFactorToViewportSize(attr, viewportSize);
+ WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr);
+
+ // FIXME: Resetting here can reset more than needed. For instance it will end deferrers.
+ // This needs to be revised at some point.
+ interactionEngine->reset();
+
+ interactionEngine->setContentToDevicePixelRatio(attr.devicePixelRatio);
- interactionEngine->applyConstraints(computeViewportConstraints());
+ interactionEngine->setAllowsUserScaling(!!attr.userScalable);
+ interactionEngine->setCSSScaleBounds(attr.minimumScale, attr.maximumScale);
+
+ if (!interactionEngine->hadUserInteraction() && !pageIsSuspended)
+ interactionEngine->setCSSScale(attr.initialScale);
+
+ this->attributes = attr;
+ q->experimental()->viewportInfo()->didUpdateViewportConstraints();
+
+ // If the web app successively changes the viewport on purpose
+ // it wants to be in control and we should disable animations.
+ interactionEngine->ensureContentWithinViewportBoundary(/*immediate*/ true);
}
void QQuickWebViewFlickablePrivate::updateViewportSize()
@@ -631,46 +757,36 @@ void QQuickWebViewFlickablePrivate::updateViewportSize()
if (viewportSize.isEmpty() || !interactionEngine)
return;
- flickProvider->setViewportSize(viewportSize);
+ WebPreferences* wkPrefs = webPageProxy->pageGroup()->preferences();
+ wkPrefs->setDeviceWidth(viewportSize.width());
+ wkPrefs->setDeviceHeight(viewportSize.height());
// Let the WebProcess know about the new viewport size, so that
// it can resize the content accordingly.
webPageProxy->setViewportSize(viewportSize);
- interactionEngine->applyConstraints(computeViewportConstraints());
- _q_commitScaleChange();
+ _q_contentViewportChanged(QPointF());
}
-void QQuickWebViewFlickablePrivate::_q_commitScaleChange()
+void QQuickWebViewFlickablePrivate::_q_contentViewportChanged(const QPointF& trajectoryVector)
{
- DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
- if (!drawingArea)
- return;
-
Q_Q(QQuickWebView);
// This is only for our QML ViewportInfo debugging API.
q->experimental()->viewportInfo()->didUpdateCurrentScale();
- const QRect visibleRect(visibleContentsRect());
- float scale = pageView->contentsScale();
-
- drawingArea->setVisibleContentsRectForScaling(visibleRect, scale);
- webPageProxy->setFixedVisibleContentRect(visibleRect);
-}
-
-void QQuickWebViewPrivate::_q_commitPositionChange(const QPointF& trajectoryVector)
-{
DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
if (!drawingArea)
return;
const QRect visibleRect(visibleContentsRect());
- drawingArea->setVisibleContentsRectForPanning(visibleRect, trajectoryVector);
+ float scale = pageView->contentsScale();
- if (!trajectoryVector.isNull())
- return;
+ QRectF accurateVisibleRect(q->boundingRect());
+ accurateVisibleRect.translate(contentPos());
+ drawingArea->setVisibleContentsRect(visibleRect, scale, trajectoryVector, FloatPoint(accurateVisibleRect.x(), accurateVisibleRect.y()));
- webPageProxy->setFixedVisibleContentRect(visibleRect);
+ // Ensure that updatePaintNode is always called before painting.
+ pageView->update();
}
void QQuickWebViewFlickablePrivate::_q_suspend()
@@ -687,99 +803,35 @@ void QQuickWebViewFlickablePrivate::_q_resume()
pageIsSuspended = false;
webPageProxy->resumeActiveDOMObjectsAndAnimations();
- if (isTransitioningToNewPage) {
- isTransitioningToNewPage = false;
- postTransitionState->apply();
- }
-
- // FIXME: Revise this.
- _q_commitScaleChange();
+ _q_contentViewportChanged(QPointF());
}
void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos)
{
- if (isTransitioningToNewPage) {
- postTransitionState->position = pos;
- return;
- }
-
interactionEngine->pagePositionRequest(pos);
}
void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize)
{
Q_Q(QQuickWebView);
- // FIXME: We probably want to handle suspend here as well
- if (isTransitioningToNewPage) {
- postTransitionState->contentsSize = newSize;
- return;
- }
-
pageView->setContentsSize(newSize);
q->experimental()->viewportInfo()->didUpdateContentsSize();
}
-QtViewportInteractionEngine::Constraints QQuickWebViewFlickablePrivate::computeViewportConstraints()
-{
- Q_Q(QQuickWebView);
-
- QtViewportInteractionEngine::Constraints newConstraints;
- QSize availableSize = q->boundingRect().size().toSize();
-
- // Return default values for zero sized viewport.
- if (availableSize.isEmpty())
- return newConstraints;
-
- WebPreferences* wkPrefs = webPageProxy->pageGroup()->preferences();
-
- // FIXME: Remove later; Hardcode some values for now to make sure the DPI adjustment is being tested.
- wkPrefs->setDeviceDPI(240);
- wkPrefs->setDeviceWidth(480);
- wkPrefs->setDeviceHeight(720);
-
- int minimumLayoutFallbackWidth = qMax<int>(wkPrefs->layoutFallbackWidth(), availableSize.width());
-
- WebCore::ViewportAttributes attr = WebCore::computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, wkPrefs->deviceWidth(), wkPrefs->deviceHeight(), wkPrefs->deviceDPI(), availableSize);
- WebCore::restrictMinimumScaleFactorToViewportSize(attr, availableSize);
- WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr);
-
- newConstraints.initialScale = attr.initialScale;
- newConstraints.minimumScale = attr.minimumScale;
- newConstraints.maximumScale = attr.maximumScale;
- newConstraints.devicePixelRatio = attr.devicePixelRatio;
- newConstraints.isUserScalable = !!attr.userScalable;
- newConstraints.layoutSize = attr.layoutSize;
-
- q->experimental()->viewportInfo()->didUpdateViewportConstraints();
-
- return newConstraints;
-}
-
-void QQuickWebViewFlickablePrivate::PostTransitionState::apply()
-{
- p->interactionEngine->reset();
- p->interactionEngine->applyConstraints(p->computeViewportConstraints());
- p->interactionEngine->pagePositionRequest(position);
-
- if (contentsSize.isValid()) {
- p->pageView->setContentsSize(contentsSize);
- p->q_ptr->experimental()->viewportInfo()->didUpdateContentsSize();
- }
-
- position = QPoint();
- contentsSize = QSize();
-}
-
/*!
- \qmlsignal WebView::onNavigationRequested(request)
+ \qmlsignal WebView::onNavigationRequested(WebNavigationRequest request)
- This signal is emitted for every navigation request. The request object contains url, button and modifiers properties
- describing the navigation action, e.g. "a middle click with shift key pressed to 'http://qt-project.org'".
+ This signal is emitted for every navigation request. The request object contains url,
+ button and modifiers properties describing the navigation action, e.g. "a middle click
+ with shift key pressed to 'http://qt-project.org'".
- The navigation will be accepted by default. To change that, one can set the action property to WebView.IgnoreRequest to reject
- the request or WebView.DownloadRequest to trigger a download instead of navigating to the url.
+ The navigation will be accepted by default. To change that, one can set the action
+ property to WebView.IgnoreRequest to reject the request or WebView.DownloadRequest to
+ trigger a download instead of navigating to the url.
The request object cannot be used after the signal handler function ends.
+
+ \sa WebNavigationRequest
*/
QQuickWebViewAttached::QQuickWebViewAttached(QObject* object)
@@ -833,6 +885,49 @@ void QQuickWebViewExperimental::setTransparentBackground(bool enable)
d->setTransparentBackground(enable);
}
+bool QQuickWebViewExperimental::useDefaultContentItemSize() const
+{
+ Q_D(const QQuickWebView);
+ return d->m_useDefaultContentItemSize;
+}
+
+void QQuickWebViewExperimental::setUseDefaultContentItemSize(bool enable)
+{
+ Q_D(QQuickWebView);
+ d->m_useDefaultContentItemSize = enable;
+}
+
+/*!
+ \internal
+
+ \qmlproperty int WebViewExperimental::preferredMinimumContentsWidth
+ \brief Minimum contents width when not overriden by the page itself.
+
+ Unless the page defines how contents should be laid out, using e.g.
+ the viewport meta tag, it is laid out given the width of the viewport
+ (in CSS units).
+
+ This setting can be used to enforce a minimum width when the page
+ does not define a width itself. This is useful for laying out pages
+ designed for big screens, commonly knows as desktop pages, on small
+ devices.
+
+ The default value is 0, but the value of 980 is recommented for small
+ screens as it provides a good trade off between legitable pages and
+ non-broken content.
+ */
+int QQuickWebViewExperimental::preferredMinimumContentsWidth() const
+{
+ Q_D(const QQuickWebView);
+ return d->webPageProxy->pageGroup()->preferences()->layoutFallbackWidth();
+}
+
+void QQuickWebViewExperimental::setPreferredMinimumContentsWidth(int width)
+{
+ Q_D(QQuickWebView);
+ d->webPageProxy->pageGroup()->preferences()->setLayoutFallbackWidth(width);
+}
+
void QQuickWebViewExperimental::setFlickableViewportEnabled(bool enable)
{
s_flickableViewportEnabled = enable;
@@ -843,6 +938,17 @@ bool QQuickWebViewExperimental::flickableViewportEnabled()
return s_flickableViewportEnabled;
}
+/*!
+ \internal
+
+ \qmlmethod void WebViewExperimental::postMessage(string message)
+
+ \brief Post a message to an onmessage function registered with the navigator.qt object
+ by JavaScript code executing on the page.
+
+ \sa onMessageReceived
+*/
+
void QQuickWebViewExperimental::postMessage(const QString& message)
{
Q_D(QQuickWebView);
@@ -966,6 +1072,105 @@ void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelec
emit itemSelectorChanged();
}
+QDeclarativeComponent* QQuickWebViewExperimental::filePicker() const
+{
+ Q_D(const QQuickWebView);
+ return d->filePicker;
+}
+
+void QQuickWebViewExperimental::setFilePicker(QDeclarativeComponent* filePicker)
+{
+ Q_D(QQuickWebView);
+ if (d->filePicker == filePicker)
+ return;
+ d->filePicker = filePicker;
+ emit filePickerChanged();
+}
+
+QDeclarativeComponent* QQuickWebViewExperimental::databaseQuotaDialog() const
+{
+ Q_D(const QQuickWebView);
+ return d->databaseQuotaDialog;
+}
+
+void QQuickWebViewExperimental::setDatabaseQuotaDialog(QDeclarativeComponent* databaseQuotaDialog)
+{
+ Q_D(QQuickWebView);
+ if (d->databaseQuotaDialog == databaseQuotaDialog)
+ return;
+ d->databaseQuotaDialog = databaseQuotaDialog;
+ emit databaseQuotaDialogChanged();
+}
+
+QString QQuickWebViewExperimental::userAgent() const
+{
+ Q_D(const QQuickWebView);
+ return d->webPageProxy->userAgent();
+}
+
+void QQuickWebViewExperimental::setUserAgent(const QString& userAgent)
+{
+ Q_D(QQuickWebView);
+ if (userAgent == QString(d->webPageProxy->userAgent()))
+ return;
+
+ d->webPageProxy->setUserAgent(userAgent);
+ emit userAgentChanged();
+}
+
+/*!
+ \internal
+
+ \qmlproperty real WebViewExperimental::devicePixelRatio
+ \brief The ratio between the CSS units and device pixels when the content is unscaled.
+
+ When designing touch-friendly contents, knowing the approximated target size on a device
+ is important for contents providers in order to get the intented layout and element
+ sizes.
+
+ As most first generation touch devices had a PPI of approximately 160, this became a
+ de-facto value, when used in conjunction with the viewport meta tag.
+
+ Devices with a higher PPI learning towards 240 or 320, applies a pre-scaling on all
+ content, of either 1.5 or 2.0, not affecting the CSS scale or pinch zooming.
+
+ This value can be set using this property and it is exposed to CSS media queries using
+ the -webkit-device-pixel-ratio query.
+
+ For instance, if you want to load an image without having it upscaled on a web view
+ using a device pixel ratio of 2.0 it can be done by loading an image of say 100x100
+ pixels but showing it at half the size.
+
+ FIXME: Move documentation example out in separate files
+
+ @media (-webkit-min-device-pixel-ratio: 1.5) {
+ .icon {
+ width: 50px;
+ height: 50px;
+ url: "/images/icon@2x.png"; // This is actually a 100x100 image
+ }
+ }
+
+ If the above is used on a device with device pixel ratio of 1.5, it will be scaled
+ down but still provide a better looking image.
+ */
+
+double QQuickWebViewExperimental::devicePixelRatio() const
+{
+ Q_D(const QQuickWebView);
+ return d->webPageProxy->pageGroup()->preferences()->devicePixelRatio();
+}
+
+void QQuickWebViewExperimental::setDevicePixelRatio(double devicePixelRatio)
+{
+ Q_D(QQuickWebView);
+ if (devicePixelRatio == this->devicePixelRatio())
+ return;
+
+ d->webPageProxy->pageGroup()->preferences()->setDevicePixelRatio(devicePixelRatio);
+ emit devicePixelRatioChanged();
+}
+
QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, int index)
{
const QObjectList children = property->object->children();
@@ -1052,80 +1257,18 @@ QQuickWebPage* QQuickWebViewExperimental::page()
return q_ptr->page();
}
-QDeclarativeListProperty<QObject> QQuickWebViewExperimental::flickableData()
-{
- Q_D(const QQuickWebView);
- ASSERT(d->flickProvider);
- return d->flickProvider->flickableData();
-}
-
-QQuickItem* QQuickWebViewExperimental::contentItem()
-{
- Q_D(QQuickWebView);
- ASSERT(d->flickProvider);
- return d->flickProvider->contentItem();
-}
-
-qreal QQuickWebViewExperimental::contentWidth() const
-{
- Q_D(const QQuickWebView);
- ASSERT(d->flickProvider);
- return d->flickProvider->contentWidth();
-}
-
-void QQuickWebViewExperimental::setContentWidth(qreal width)
-{
- Q_D(QQuickWebView);
- ASSERT(d->flickProvider);
- d->userDidOverrideContentWidth = true;
- d->flickProvider->setContentWidth(width);
-}
-
-qreal QQuickWebViewExperimental::contentHeight() const
-{
- Q_D(const QQuickWebView);
- ASSERT(d->flickProvider);
- return d->flickProvider->contentHeight();
-}
-
-void QQuickWebViewExperimental::setContentHeight(qreal height)
-{
- Q_D(QQuickWebView);
- ASSERT(d->flickProvider);
- d->userDidOverrideContentHeight = true;
- d->flickProvider->setContentHeight(height);
-}
-
-qreal QQuickWebViewExperimental::contentX() const
-{
- Q_D(const QQuickWebView);
- ASSERT(d->flickProvider);
- return d->flickProvider->contentX();
-}
-
-void QQuickWebViewExperimental::setContentX(qreal x)
-{
- Q_D(QQuickWebView);
- ASSERT(d->flickProvider);
- d->flickProvider->setContentX(x);
-}
-
-qreal QQuickWebViewExperimental::contentY() const
-{
- Q_D(const QQuickWebView);
- ASSERT(d->flickProvider);
- return d->flickProvider->contentY();
-}
+/*!
+ \qmlclass WebView QWebView
+ \inqmlmodule QtWebKit 3.0
+*/
-void QQuickWebViewExperimental::setContentY(qreal y)
-{
- Q_D(QQuickWebView);
- ASSERT(d->flickProvider);
- d->flickProvider->setContentY(y);
-}
+/*!
+ \qmlmethod WebView(Item parent)
+ \brief Constructs a WebView with a parent.
+*/
QQuickWebView::QQuickWebView(QQuickItem* parent)
- : QQuickItem(parent)
+ : QQuickFlickable(parent)
, d_ptr(createPrivateObject(this))
, m_experimental(new QQuickWebViewExperimental(this))
{
@@ -1134,13 +1277,12 @@ QQuickWebView::QQuickWebView(QQuickItem* parent)
}
QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, QQuickItem* parent)
- : QQuickItem(parent)
+ : QQuickFlickable(parent)
, d_ptr(createPrivateObject(this))
, m_experimental(new QQuickWebViewExperimental(this))
{
Q_D(QQuickWebView);
d->initialize(contextRef, pageGroupRef);
- setClip(true);
}
QQuickWebView::~QQuickWebView()
@@ -1208,6 +1350,13 @@ QUrl QQuickWebView::icon() const
return d->m_iconURL;
}
+/*!
+ \qmlproperty int WebView::loadProgress
+ \brief The progress of loading the current web page.
+
+ The range is from 0 to 100.
+*/
+
int QQuickWebView::loadProgress() const
{
Q_D(const QQuickWebView);
@@ -1226,6 +1375,11 @@ bool QQuickWebView::canGoForward() const
return d->webPageProxy->canGoForward();
}
+/*!
+ \qmlproperty bool WebView::loading
+ \brief True if the web view is currently loading a web page, false otherwise.
+*/
+
bool QQuickWebView::loading() const
{
Q_D(const QQuickWebView);
@@ -1233,30 +1387,50 @@ bool QQuickWebView::loading() const
return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
}
+/*!
+ \internal
+ */
+
QPointF QQuickWebView::mapToWebContent(const QPointF& pointInViewCoordinates) const
{
Q_D(const QQuickWebView);
return d->pageView->transformFromItem().map(pointInViewCoordinates);
}
+/*!
+ \internal
+ */
+
QRectF QQuickWebView::mapRectToWebContent(const QRectF& rectInViewCoordinates) const
{
Q_D(const QQuickWebView);
return d->pageView->transformFromItem().mapRect(rectInViewCoordinates);
}
+/*!
+ \internal
+ */
+
QPointF QQuickWebView::mapFromWebContent(const QPointF& pointInCSSCoordinates) const
{
Q_D(const QQuickWebView);
return d->pageView->transformToItem().map(pointInCSSCoordinates);
}
+/*!
+ \internal
+ */
QRectF QQuickWebView::mapRectFromWebContent(const QRectF& rectInCSSCoordinates) const
{
Q_D(const QQuickWebView);
return d->pageView->transformToItem().mapRect(rectInCSSCoordinates);
}
+/*!
+ \qmlproperty string WebView::title
+ \brief The title of the loaded page.
+*/
+
QString QQuickWebView::title() const
{
Q_D(const QQuickWebView);
@@ -1287,10 +1461,16 @@ QVariant QQuickWebView::inputMethodQuery(Qt::InputMethodQuery property) const
return int(Qt::InputMethodHints(state.inputMethodHints));
default:
// Rely on the base implementation for ImEnabled, ImHints and ImPreferredLanguage.
- return QQuickItem::inputMethodQuery(property);
+ return QQuickFlickable::inputMethodQuery(property);
}
}
+/*!
+ \preliminary
+
+ The experimental module consisting on experimental API which will break
+ from version to version.
+*/
QQuickWebViewExperimental* QQuickWebView::experimental() const
{
return m_experimental;
@@ -1301,6 +1481,9 @@ QQuickWebViewAttached* QQuickWebView::qmlAttachedProperties(QObject* object)
return new QQuickWebViewAttached(object);
}
+/*!
+ \internal
+*/
void QQuickWebView::platformInitialize()
{
JSC::initializeThreading();
@@ -1310,7 +1493,7 @@ void QQuickWebView::platformInitialize()
void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
{
Q_D(QQuickWebView);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
if (newGeometry.size() != oldGeometry.size())
d->updateViewportSize();
}
@@ -1318,7 +1501,7 @@ void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& old
void QQuickWebView::componentComplete()
{
Q_D(QQuickWebView);
- QQuickItem::componentComplete();
+ QQuickFlickable::componentComplete();
d->onComponentComplete();
d->updateViewportSize();
@@ -1357,11 +1540,21 @@ void QQuickWebView::focusOutEvent(QFocusEvent* event)
void QQuickWebView::touchEvent(QTouchEvent* event)
{
Q_D(QQuickWebView);
- if (d->m_dialogRunnerActive) {
+ if (d->m_dialogActive) {
event->ignore();
return;
}
+ bool lockingDisabled = flickableDirection() != AutoFlickDirection
+ || event->touchPoints().size() != 1
+ || width() >= contentWidth()
+ || height() >= contentHeight();
+
+ if (!lockingDisabled)
+ d->axisLocker.update(event);
+ else
+ d->axisLocker.reset();
+
forceActiveFocus();
d->pageView->eventHandler()->handleTouchEvent(event);
}
@@ -1445,7 +1638,7 @@ void QQuickWebView::dropEvent(QDropEvent* event)
bool QQuickWebView::event(QEvent* ev)
{
// Re-implemented for possible future use without breaking binary compatibility.
- return QQuickItem::event(ev);
+ return QQuickFlickable::event(ev);
}
WKPageRef QQuickWebView::pageRef() const
@@ -1454,13 +1647,52 @@ WKPageRef QQuickWebView::pageRef() const
return toAPI(d->webPageProxy.get());
}
+QPointF QQuickWebView::contentPos() const
+{
+ Q_D(const QQuickWebView);
+ return d->contentPos();
+}
+
+void QQuickWebView::setContentPos(const QPointF& pos)
+{
+ Q_D(QQuickWebView);
+ d->setContentPos(pos);
+}
+
+void QQuickWebView::handleFlickableMousePress(const QPointF& position, qint64 eventTimestampMillis)
+{
+ Q_D(QQuickWebView);
+ d->axisLocker.setReferencePosition(position);
+ QMouseEvent mouseEvent(QEvent::MouseButtonPress, position, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ mouseEvent.setTimestamp(eventTimestampMillis);
+ QQuickFlickable::mousePressEvent(&mouseEvent);
+}
+
+void QQuickWebView::handleFlickableMouseMove(const QPointF& position, qint64 eventTimestampMillis)
+{
+ Q_D(QQuickWebView);
+ QMouseEvent mouseEvent(QEvent::MouseMove, d->axisLocker.adjust(position), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ mouseEvent.setTimestamp(eventTimestampMillis);
+ QQuickFlickable::mouseMoveEvent(&mouseEvent);
+}
+
+void QQuickWebView::handleFlickableMouseRelease(const QPointF& position, qint64 eventTimestampMillis)
+{
+ Q_D(QQuickWebView);
+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease, d->axisLocker.adjust(position), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ d->axisLocker.reset();
+ mouseEvent.setTimestamp(eventTimestampMillis);
+ QQuickFlickable::mouseReleaseEvent(&mouseEvent);
+}
+
/*!
- Loads the specified \a html as the content of the web view.
+ \qmlmethod void WebView::loadHtml(string html, url baseUrl, url unreachableUrl)
+ \brief Loads the specified \a html as the content of the web view.
External objects such as stylesheets or images referenced in the HTML
document are located relative to \a baseUrl.
- \sa load()
+ \sa WebView::url
*/
void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl)
{
@@ -1480,4 +1712,38 @@ void QQuickWebView::updateContentsSize(const QSizeF& size)
d->updateContentsSize(size);
}
+qreal QQuickWebView::zoomFactor() const
+{
+ Q_D(const QQuickWebView);
+ return d->zoomFactor();
+}
+
+void QQuickWebView::setZoomFactor(qreal factor)
+{
+
+ Q_D(QQuickWebView);
+ d->setZoomFactor(factor);
+}
+
+struct JSCallbackClosure {
+ QPointer<QObject> receiver;
+ QByteArray method;
+};
+
+static void javaScriptCallback(WKSerializedScriptValueRef, WKErrorRef, void* context)
+{
+ JSCallbackClosure* closure = reinterpret_cast<JSCallbackClosure*>(context);
+ QMetaObject::invokeMethod(closure->receiver, closure->method);
+ delete closure;
+}
+
+void QQuickWebView::runJavaScriptInMainFrame(const QString &script, QObject *receiver, const char *method)
+{
+ Q_D(QQuickWebView);
+ JSCallbackClosure* closure = new JSCallbackClosure;
+ closure->receiver = receiver;
+ closure->method = method;
+ d->webPageProxy.get()->runJavaScriptInMainFrame(script, ScriptValueCallback::create(closure, javaScriptCallback));
+}
+
#include "moc_qquickwebview_p.cpp"
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
index 5302916eb..916f2282d 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
@@ -23,8 +23,9 @@
#include "qquickurlschemedelegate_p.h"
#include "qwebkitglobal.h"
-#include <QtDeclarative/qdeclarativelist.h>
+#include <QtQml/qqmllist.h>
#include <QtQuick/qquickitem.h>
+#include <private/qquickflickable_p.h>
class QWebNavigationRequest;
class QDeclarativeComponent;
@@ -46,6 +47,10 @@ class PlatformWebView;
namespace WebKit {
class QtRefCountedNetworkRequestData;
+class QtViewportInteractionEngine;
+class QtWebPageLoadClient;
+class QtWebPagePolicyClient;
+class QtWebPageUIClient;
}
namespace WTF {
@@ -59,13 +64,14 @@ typedef const struct OpaqueWKPage* WKPageRef;
QT_BEGIN_NAMESPACE
class QPainter;
class QUrl;
+class QQuickFlickable;
QT_END_NAMESPACE
// Instantiating the WebView in C++ is only possible by creating
// a QDeclarativeComponent as the initialization depends on the
// componentComplete method being called.
-class QWEBKIT_EXPORT QQuickWebView : public QQuickItem {
+class QWEBKIT_EXPORT QQuickWebView : public QQuickFlickable {
Q_OBJECT
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
@@ -138,6 +144,11 @@ public:
void updateContentsSize(const QSizeF&);
QPointF pageItemPos();
+ // Private C++-only API.
+ qreal zoomFactor() const;
+ void setZoomFactor(qreal);
+ void runJavaScriptInMainFrame(const QString& script, QObject* receiver, const char* method);
+
public Q_SLOTS:
void loadHtml(const QString& html, const QUrl& baseUrl = QUrl());
@@ -182,16 +193,20 @@ protected:
private:
Q_DECLARE_PRIVATE(QQuickWebView)
+ void handleFlickableMousePress(const QPointF& position, qint64 eventTimestampMillis);
+ void handleFlickableMouseMove(const QPointF& position, qint64 eventTimestampMillis);
+ void handleFlickableMouseRelease(const QPointF& position, qint64 eventTimestampMillis);
+
+ QPointF contentPos() const;
+ void setContentPos(const QPointF&);
+
QQuickWebView(WKContextRef, WKPageGroupRef, QQuickItem* parent = 0);
WKPageRef pageRef() const;
Q_PRIVATE_SLOT(d_func(), void _q_suspend());
Q_PRIVATE_SLOT(d_func(), void _q_resume());
- Q_PRIVATE_SLOT(d_func(), void _q_commitPositionChange(const QPointF&));
- Q_PRIVATE_SLOT(d_func(), void _q_commitScaleChange());
+ Q_PRIVATE_SLOT(d_func(), void _q_contentViewportChanged(const QPointF&));
- 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*));
@@ -200,9 +215,10 @@ private:
QScopedPointer<QQuickWebViewPrivate> d_ptr;
QQuickWebViewExperimental* m_experimental;
- friend class QtWebPageLoadClient;
- friend class QtWebPagePolicyClient;
- friend class QtWebPageUIClient;
+ friend class WebKit::QtViewportInteractionEngine;
+ friend class WebKit::QtWebPageLoadClient;
+ friend class WebKit::QtWebPagePolicyClient;
+ friend class WebKit::QtWebPageUIClient;
friend class WTR::PlatformWebView;
friend class QQuickWebViewExperimental;
};
@@ -231,14 +247,9 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject {
Q_OBJECT
Q_PROPERTY(QQuickWebPage* page READ page CONSTANT FINAL)
- // QML Flickable API.
- Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged)
- Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged)
- Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged)
- 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(bool useDefaultContentItemSize WRITE setUseDefaultContentItemSize READ useDefaultContentItemSize)
+ Q_PROPERTY(int preferredMinimumContentsWidth WRITE setPreferredMinimumContentsWidth READ preferredMinimumContentsWidth)
Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL)
Q_PROPERTY(QDeclarativeComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged)
@@ -248,9 +259,13 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject {
Q_PROPERTY(QDeclarativeComponent* proxyAuthenticationDialog READ proxyAuthenticationDialog WRITE setProxyAuthenticationDialog NOTIFY proxyAuthenticationDialogChanged)
Q_PROPERTY(QDeclarativeComponent* certificateVerificationDialog READ certificateVerificationDialog WRITE setCertificateVerificationDialog NOTIFY certificateVerificationDialogChanged)
Q_PROPERTY(QDeclarativeComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged)
+ Q_PROPERTY(QDeclarativeComponent* filePicker READ filePicker WRITE setFilePicker NOTIFY filePickerChanged)
+ Q_PROPERTY(QDeclarativeComponent* databaseQuotaDialog READ databaseQuotaDialog WRITE setDatabaseQuotaDialog NOTIFY databaseQuotaDialogChanged)
Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL)
Q_PROPERTY(QWebViewportInfo* viewportInfo READ viewportInfo CONSTANT FINAL)
Q_PROPERTY(QDeclarativeListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates)
+ Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent NOTIFY userAgentChanged)
+ Q_PROPERTY(double devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged)
Q_ENUMS(NavigationRequestActionExperimental)
public:
@@ -275,6 +290,14 @@ public:
void setItemSelector(QDeclarativeComponent*);
QDeclarativeComponent* proxyAuthenticationDialog() const;
void setProxyAuthenticationDialog(QDeclarativeComponent*);
+ QDeclarativeComponent* filePicker() const;
+ void setFilePicker(QDeclarativeComponent*);
+ QDeclarativeComponent* databaseQuotaDialog() const;
+ void setDatabaseQuotaDialog(QDeclarativeComponent*);
+ QString userAgent() const;
+ void setUserAgent(const QString& userAgent);
+ double devicePixelRatio() const;
+ void setDevicePixelRatio(double);
QWebViewportInfo* viewportInfo();
@@ -287,22 +310,18 @@ public:
static int schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*);
static void schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*);
QDeclarativeListProperty<QQuickUrlSchemeDelegate> schemeDelegates();
- QDeclarativeListProperty<QObject> flickableData();
void invokeApplicationSchemeHandler(WTF::PassRefPtr<WebKit::QtRefCountedNetworkRequestData>);
void sendApplicationSchemeReply(QQuickNetworkReply*);
- QQuickItem* contentItem();
- qreal contentWidth() const;
- void setContentWidth(qreal);
- qreal contentHeight() const;
- void setContentHeight(qreal);
- qreal contentX() const;
- void setContentX(qreal);
- qreal contentY() const;
- void setContentY(qreal);
bool transparentBackground() const;
void setTransparentBackground(bool);
+ bool useDefaultContentItemSize() const;
+ void setUseDefaultContentItemSize(bool enable);
+
+ int preferredMinimumContentsWidth() const;
+ void setPreferredMinimumContentsWidth(int);
+
// C++ only
bool renderToOffscreenBuffer() const;
void setRenderToOffscreenBuffer(bool enable);
@@ -315,20 +334,22 @@ public Q_SLOTS:
void postMessage(const QString&);
Q_SIGNALS:
- void contentWidthChanged();
- void contentHeightChanged();
- void contentXChanged();
- void contentYChanged();
void alertDialogChanged();
void confirmDialogChanged();
void promptDialogChanged();
void authenticationDialogChanged();
void certificateVerificationDialogChanged();
void itemSelectorChanged();
+ void filePickerChanged();
+ void databaseQuotaDialogChanged();
void downloadRequested(QWebDownloadItem* downloadItem);
void permissionRequested(QWebPermissionRequest* permission);
void messageReceived(const QVariantMap& message);
void proxyAuthenticationDialogChanged();
+ void userAgentChanged();
+ void devicePixelRatioChanged();
+ void enterFullScreenRequested();
+ void exitFullScreenRequested();
private:
QQuickWebView* q_ptr;
@@ -336,7 +357,7 @@ private:
QObject* schemeParent;
QWebViewportInfo* m_viewportInfo;
- friend class QtWebPageUIClient;
+ friend class WebKit::QtWebPageUIClient;
Q_DECLARE_PRIVATE(QQuickWebView)
Q_DECLARE_PUBLIC(QQuickWebView)
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
index 39a14a7a6..417618d0a 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
@@ -21,36 +21,36 @@
#ifndef qquickwebview_p_p_h
#define qquickwebview_p_p_h
-#include "DrawingAreaProxy.h"
-#include "QtDialogRunner.h"
-#include "QtFlickProvider.h"
#include "QtPageClient.h"
-#include "QtViewportInteractionEngine.h"
-#include "QtWebPageLoadClient.h"
-#include "QtWebPagePolicyClient.h"
#include "QtWebPageUIClient.h"
#include "QtWebUndoController.h"
-#include "WebPageProxy.h"
#include "qquickwebview_p.h"
#include "qquickwebpage_p.h"
+#include <QtCore/QElapsedTimer>
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
+#include <WebCore/ViewportArguments.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
namespace WebKit {
class DownloadProxy;
+class DrawingAreaProxy;
+class QtDialogRunner;
+class QtViewportInteractionEngine;
class QtWebContext;
+class QtWebPageLoadClient;
+class QtWebPagePolicyClient;
class WebPageProxy;
}
+
class QWebNavigationHistory;
class QWebViewportInfo;
QT_BEGIN_NAMESPACE
class QDeclarativeComponent;
-class QFileDialog;
QT_END_NAMESPACE
class QQuickWebViewPrivate {
@@ -67,8 +67,8 @@ public:
virtual void initialize(WKContextRef contextRef = 0, WKPageGroupRef pageGroupRef = 0);
- void enableMouseEvents();
- void disableMouseEvents();
+ virtual void enableMouseEvents() { }
+ virtual void disableMouseEvents() { }
virtual QPointF pageItemPos();
virtual void updateContentsSize(const QSizeF&) { }
@@ -77,30 +77,29 @@ public:
virtual void onComponentComplete();
virtual void loadDidCommit() { }
virtual void didFinishFirstNonEmptyLayout() { }
- virtual void didChangeViewportProperties(const WebCore::ViewportArguments& args) { }
- void didChangeLoadingState(QWebLoadRequest* loadRequest);
+ virtual void didChangeViewportProperties(const WebCore::ViewportAttributes& attr) { }
void didChangeBackForwardList();
void setNeedsDisplay();
- virtual QtViewportInteractionEngine* viewportInteractionEngine() { return 0; }
+ virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return 0; }
virtual void updateViewportSize() { }
void updateTouchViewportSize();
virtual void _q_suspend() { }
virtual void _q_resume() { }
+ virtual void _q_contentViewportChanged(const QPointF& trajectory) { };
- virtual void _q_commitScaleChange() { }
- void _q_commitPositionChange(const QPointF&);
+ virtual qreal zoomFactor() const { return 1; }
+ virtual void setZoomFactor(qreal) { }
- 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);
- void chooseFiles(WKOpenPanelResultListenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType);
+ void chooseFiles(WKOpenPanelResultListenerRef, const QStringList& selectedFileNames, WebKit::QtWebPageUIClient::FileChooserType);
+ quint64 exceededDatabaseQuota(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage);
void runJavaScriptAlert(const QString&);
bool runJavaScriptConfirm(const QString&);
QString runJavaScriptPrompt(const QString&, const QString& defaultValue, bool& ok);
@@ -109,7 +108,7 @@ 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 execDialogRunner(WebKit::QtDialogRunner&);
void setRenderToOffscreenBuffer(bool enable) { m_renderToOffscreenBuffer = enable; }
void setTransparentBackground(bool);
@@ -121,8 +120,13 @@ public:
bool transparentBackground() const;
void setNavigatorQtObjectEnabled(bool);
+ QPointF contentPos() const;
+ void setContentPos(const QPointF&);
+
QRect visibleContentsRect() const;
+ void setDialogActive(bool active) { m_dialogActive = active; }
+
// PageClient.
WebCore::IntSize viewSize() const;
void didReceiveMessageFromNavigatorQtObject(const String& message);
@@ -130,26 +134,46 @@ public:
virtual void didChangeContentsSize(const QSize& newSize) { }
void processDidCrash();
void didRelaunchProcess();
- PassOwnPtr<DrawingAreaProxy> createDrawingAreaProxy();
- void handleDownloadRequest(DownloadProxy*);
+ PassOwnPtr<WebKit::DrawingAreaProxy> createDrawingAreaProxy();
+ void handleDownloadRequest(WebKit::DownloadProxy*);
protected:
+ class FlickableAxisLocker {
+ QQuickFlickable::FlickableDirection m_allowedDirection;
+
+ QElapsedTimer m_time;
+ QPointF m_initialScreenPosition;
+ QPointF m_lockReferencePosition;
+ int m_sampleCount;
+
+ QVector2D touchVelocity(const QTouchEvent* event);
+
+ public:
+ FlickableAxisLocker();
+
+ void update(const QTouchEvent* event);
+ void setReferencePosition(const QPointF&);
+ void reset();
+ QPointF adjust(const QPointF&);
+ };
+
QQuickWebViewPrivate(QQuickWebView* viewport);
- RefPtr<QtWebContext> context;
+ RefPtr<WebKit::QtWebContext> context;
RefPtr<WebKit::WebPageProxy> webPageProxy;
- QtPageClient pageClient;
- QtWebUndoController undoController;
+ WebKit::QtPageClient pageClient;
+ WebKit::QtWebUndoController undoController;
OwnPtr<QWebNavigationHistory> navigationHistory;
OwnPtr<QWebPreferences> preferences;
- QScopedPointer<QtWebPageLoadClient> pageLoadClient;
- QScopedPointer<QtWebPagePolicyClient> pagePolicyClient;
- QScopedPointer<QtWebPageUIClient> pageUIClient;
+ QScopedPointer<WebKit::QtWebPageLoadClient> pageLoadClient;
+ QScopedPointer<WebKit::QtWebPagePolicyClient> pagePolicyClient;
+ QScopedPointer<WebKit::QtWebPageUIClient> pageUIClient;
QScopedPointer<QQuickWebPage> pageView;
QQuickWebView* q_ptr;
- QtFlickProvider* flickProvider;
+
+ FlickableAxisLocker axisLocker;
QDeclarativeComponent* alertDialog;
QDeclarativeComponent* confirmDialog;
@@ -158,17 +182,15 @@ protected:
QDeclarativeComponent* certificateVerificationDialog;
QDeclarativeComponent* itemSelector;
QDeclarativeComponent* proxyAuthenticationDialog;
+ QDeclarativeComponent* filePicker;
+ QDeclarativeComponent* databaseQuotaDialog;
- WebCore::ViewportArguments viewportArguments;
- QFileDialog* fileDialog;
- WKOpenPanelResultListenerRef openPanelResultListener;
+ WebCore::ViewportAttributes attributes;
- bool userDidOverrideContentWidth;
- bool userDidOverrideContentHeight;
+ bool m_useDefaultContentItemSize;
bool m_navigatorQtObjectEnabled;
bool m_renderToOffscreenBuffer;
- bool m_loadStartedSignalSent;
- bool m_dialogRunnerActive;
+ bool m_dialogActive;
QUrl m_iconURL;
QUrl m_deferedUrlToLoad;
};
@@ -180,6 +202,11 @@ public:
virtual void initialize(WKContextRef contextRef = 0, WKPageGroupRef pageGroupRef = 0);
virtual void updateViewportSize();
+ virtual void enableMouseEvents();
+ virtual void disableMouseEvents();
+
+ qreal zoomFactor() const;
+ void setZoomFactor(qreal);
};
class QQuickWebViewFlickablePrivate : public QQuickWebViewPrivate {
@@ -196,39 +223,19 @@ public:
virtual void onComponentComplete();
virtual void loadDidCommit();
virtual void didFinishFirstNonEmptyLayout();
- virtual void didChangeViewportProperties(const WebCore::ViewportArguments& args);
- virtual QtViewportInteractionEngine* viewportInteractionEngine() { return interactionEngine.data(); }
+ virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&);
+ virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return interactionEngine.data(); }
virtual void updateViewportSize();
virtual void _q_suspend();
virtual void _q_resume();
- virtual void _q_commitScaleChange();
+ virtual void _q_contentViewportChanged(const QPointF& trajectory);
virtual void pageDidRequestScroll(const QPoint& pos);
virtual void didChangeContentsSize(const QSize& newSize);
- QtViewportInteractionEngine::Constraints computeViewportConstraints();
-
private:
- // This class is responsible for collecting and applying all properties
- // on the viewport item, when transitioning from page A to page B is finished.
- // See more at https://trac.webkit.org/wiki/QtWebKitLayoutInteraction
- class PostTransitionState {
- public:
- PostTransitionState(QQuickWebViewFlickablePrivate* parent)
- : p(parent)
- { }
-
- void apply();
-
- QQuickWebViewFlickablePrivate* p;
- QSize contentsSize;
- QPoint position;
- };
-
- QScopedPointer<QtViewportInteractionEngine> interactionEngine;
- OwnPtr<PostTransitionState> postTransitionState;
- bool isTransitioningToNewPage;
+ QScopedPointer<WebKit::QtViewportInteractionEngine> interactionEngine;
bool pageIsSuspended;
bool loadSuccessDispatchIsPending;
};
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h
index 79659753b..69bb3dfa1 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h
@@ -26,7 +26,6 @@
#include <QUrl>
class QWebDownloadItemPrivate;
-class QtWebError;
QT_BEGIN_NAMESPACE
class QString;
@@ -34,6 +33,7 @@ QT_END_NAMESPACE
namespace WebKit {
class QtDownloadManager;
+class QtWebError;
}
class QWEBKIT_EXPORT QWebDownloadItem : public QObject {
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h
index 8815d7b76..74f55995f 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h
@@ -21,7 +21,7 @@
#define qwebiconimageprovider_p_h
#include "qwebkitglobal.h"
-#include <QtDeclarative/QDeclarativeImageProvider>
+#include <QtQuick/QQuickImageProvider>
class QWEBKIT_EXPORT QWebIconImageProvider : public QDeclarativeImageProvider {
public:
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp
index 0b249a61a..39f314c3b 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp
@@ -39,6 +39,17 @@ public:
int errorCode;
};
+/*!
+ \qmlclass WebLoadRequest QWebLoadRequest
+ \brief A utility class for the WebView::loadingChanged signal.
+
+ This class contains information about a requested load of a web page, like the URL and
+ current loading status (started, finished, failed).
+
+ \sa WebView::loadingChanged(WebLoadRequest)
+
+ \inqmlmodule QtWebKit 3.0
+*/
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))
@@ -49,16 +60,36 @@ QWebLoadRequest::~QWebLoadRequest()
{
}
+/*!
+ \qmlproperty url WebLoadRequest::url
+ \brief The URL of the load request.
+ */
QUrl QWebLoadRequest::url() const
{
return d->url;
}
+/*!
+ \qmlproperty enumeration WebLoadRequest::status
+
+ The load status of a web page load request.
+
+ \list
+ \li WebView::LoadStartedStatus - the page is currently loading.
+ \li WebView::LoadSucceededStatus - the page has been loaded with success.
+ \li WebView::LoadFailedStatus - the page has failed loading.
+ \endlist
+
+ \sa WebLoadRequest, WebView::loadingChanged(WebLoadRequest)
+*/
QQuickWebView::LoadStatus QWebLoadRequest::status() const
{
return d->status;
}
+/*!
+ \qmlproperty string WebLoadRequest::errorString
+*/
QString QWebLoadRequest::errorString() const
{
return d->errorString;
@@ -69,6 +100,9 @@ QQuickWebView::ErrorDomain QWebLoadRequest::errorDomain() const
return d->errorDomain;
}
+/*!
+ \qmlproperty int WebLoadRequest::errorCode
+*/
int QWebLoadRequest::errorCode() const
{
return d->errorCode;
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp
index ff77dae6b..b057526e1 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp
@@ -33,9 +33,9 @@
#include "WebBackForwardList.h"
#include "qwebnavigationhistory_p_p.h"
-#include <QDeclarativeEngine>
#include <QString>
#include <QUrl>
+#include <QtQml/QQmlEngine>
#include <WebKit2/WKArray.h>
#include <WebKit2/WKBackForwardListItem.h>
#include <WebKit2/WKBase.h>
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h
index 929114472..fa630754b 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h
@@ -31,7 +31,7 @@
#include <QObject>
#include <QUrl>
#include <QVariant>
-#include <qdeclarative.h>
+#include <QtQml/qqml.h>
class QAbstractListModel;
class QWebNavigationHistoryPrivate;
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp b/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp
index 835c698db..0b3f36d09 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp
@@ -32,6 +32,7 @@ QWebPreferences* QWebPreferencesPrivate::createPreferences(QQuickWebViewPrivate*
{
QWebPreferences* prefs = new QWebPreferences;
prefs->d->webViewPrivate = webViewPrivate;
+ prefs->d->initializeDefaultFontSettings();
return prefs;
}
@@ -40,6 +41,10 @@ bool QWebPreferencesPrivate::testAttribute(QWebPreferencesPrivate::WebAttribute
switch (attr) {
case AutoLoadImages:
return WKPreferencesGetLoadsImagesAutomatically(preferencesRef());
+#if ENABLE(FULLSCREEN_API)
+ case FullScreenEnabled:
+ return WKPreferencesGetFullScreenEnabled(preferencesRef());
+#endif
case JavascriptEnabled:
return WKPreferencesGetJavaScriptEnabled(preferencesRef());
case PluginsEnabled:
@@ -56,6 +61,8 @@ bool QWebPreferencesPrivate::testAttribute(QWebPreferencesPrivate::WebAttribute
return WKPreferencesGetDNSPrefetchingEnabled(preferencesRef());
case FrameFlatteningEnabled:
return WKPreferencesGetFrameFlatteningEnabled(preferencesRef());
+ case DeveloperExtrasEnabled:
+ return WKPreferencesGetDeveloperExtrasEnabled(preferencesRef());
default:
ASSERT_NOT_REACHED();
return false;
@@ -68,6 +75,11 @@ void QWebPreferencesPrivate::setAttribute(QWebPreferencesPrivate::WebAttribute a
case AutoLoadImages:
WKPreferencesSetLoadsImagesAutomatically(preferencesRef(), enable);
break;
+#if ENABLE(FULLSCREEN_API)
+ case FullScreenEnabled:
+ WKPreferencesSetFullScreenEnabled(preferencesRef(), enable);
+ break;
+#endif
case JavascriptEnabled:
WKPreferencesSetJavaScriptEnabled(preferencesRef(), enable);
break;
@@ -91,12 +103,38 @@ void QWebPreferencesPrivate::setAttribute(QWebPreferencesPrivate::WebAttribute a
break;
case FrameFlatteningEnabled:
WKPreferencesSetFrameFlatteningEnabled(preferencesRef(), enable);
+ case DeveloperExtrasEnabled:
+ WKPreferencesSetDeveloperExtrasEnabled(preferencesRef(), enable);
break;
default:
ASSERT_NOT_REACHED();
}
}
+void QWebPreferencesPrivate::initializeDefaultFontSettings()
+{
+ setFontSize(MinimumFontSize, 0);
+ setFontSize(DefaultFontSize, 16);
+ setFontSize(DefaultFixedFontSize, 13);
+
+ QFont defaultFont;
+ defaultFont.setStyleHint(QFont::Serif);
+ setFontFamily(StandardFont, defaultFont.defaultFamily());
+ setFontFamily(SerifFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Fantasy);
+ setFontFamily(FantasyFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Cursive);
+ setFontFamily(CursiveFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::SansSerif);
+ setFontFamily(SansSerifFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Monospace);
+ setFontFamily(FixedFont, defaultFont.defaultFamily());
+}
+
void QWebPreferencesPrivate::setFontFamily(QWebPreferencesPrivate::FontFamily which, const QString& family)
{
switch (which) {
@@ -208,6 +246,25 @@ void QWebPreferences::setAutoLoadImages(bool enable)
emit autoLoadImagesChanged();
}
+bool QWebPreferences::fullScreenEnabled() const
+{
+#if ENABLE(FULLSCREEN_API)
+ return d->testAttribute(QWebPreferencesPrivate::FullScreenEnabled);
+#else
+ return false;
+#endif
+}
+
+void QWebPreferences::setFullScreenEnabled(bool enable)
+{
+#if ENABLE(FULLSCREEN_API)
+ d->setAttribute(QWebPreferencesPrivate::FullScreenEnabled, enable);
+ emit fullScreenEnabledChanged();
+#else
+ UNUSED_PARAM(enable);
+#endif
+}
+
bool QWebPreferences::javascriptEnabled() const
{
return d->testAttribute(QWebPreferencesPrivate::JavascriptEnabled);
@@ -285,6 +342,17 @@ void QWebPreferences::setDnsPrefetchEnabled(bool enable)
emit dnsPrefetchEnabledChanged();
}
+bool QWebPreferences::developerExtrasEnabled() const
+{
+ return d->testAttribute(QWebPreferencesPrivate::DeveloperExtrasEnabled);
+}
+
+void QWebPreferences::setDeveloperExtrasEnabled(bool enable)
+{
+ d->setAttribute(QWebPreferencesPrivate::DeveloperExtrasEnabled, enable);
+ emit developerExtrasEnabledChanged();
+}
+
bool QWebPreferences::navigatorQtObjectEnabled() const
{
return d->webViewPrivate->navigatorQtObjectEnabled();
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h
index 82b738fbf..24859bff2 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h
@@ -32,6 +32,7 @@ public:
~QWebPreferences();
Q_PROPERTY(bool autoLoadImages READ autoLoadImages WRITE setAutoLoadImages NOTIFY autoLoadImagesChanged FINAL)
+ Q_PROPERTY(bool fullScreenEnabled READ fullScreenEnabled WRITE setFullScreenEnabled NOTIFY fullScreenEnabledChanged FINAL)
Q_PROPERTY(bool javascriptEnabled READ javascriptEnabled WRITE setJavascriptEnabled NOTIFY javascriptEnabledChanged FINAL)
Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged FINAL)
Q_PROPERTY(bool offlineWebApplicationCacheEnabled READ offlineWebApplicationCacheEnabled WRITE setOfflineWebApplicationCacheEnabled NOTIFY offlineWebApplicationCacheEnabledChanged FINAL)
@@ -41,6 +42,7 @@ public:
Q_PROPERTY(bool dnsPrefetchEnabled READ dnsPrefetchEnabled WRITE setDnsPrefetchEnabled NOTIFY dnsPrefetchEnabledChanged FINAL)
Q_PROPERTY(bool navigatorQtObjectEnabled READ navigatorQtObjectEnabled WRITE setNavigatorQtObjectEnabled NOTIFY navigatorQtObjectEnabledChanged FINAL)
Q_PROPERTY(bool frameFlatteningEnabled READ frameFlatteningEnabled WRITE setFrameFlatteningEnabled NOTIFY frameFlatteningEnabledChanged FINAL)
+ Q_PROPERTY(bool developerExtrasEnabled READ developerExtrasEnabled WRITE setDeveloperExtrasEnabled NOTIFY developerExtrasEnabledChanged FINAL)
Q_PROPERTY(QString standardFontFamily READ standardFontFamily WRITE setStandardFontFamily NOTIFY standardFontFamilyChanged FINAL)
Q_PROPERTY(QString fixedFontFamily READ fixedFontFamily WRITE setFixedFontFamily NOTIFY fixedFontFamilyChanged FINAL)
@@ -56,6 +58,9 @@ public:
bool autoLoadImages() const;
void setAutoLoadImages(bool enable);
+ bool fullScreenEnabled() const;
+ void setFullScreenEnabled(bool enable);
+
bool javascriptEnabled() const;
void setJavascriptEnabled(bool enable);
@@ -83,6 +88,9 @@ public:
bool frameFlatteningEnabled() const;
void setFrameFlatteningEnabled(bool enable);
+ bool developerExtrasEnabled() const;
+ void setDeveloperExtrasEnabled(bool enable);
+
QString standardFontFamily() const;
void setStandardFontFamily(const QString& family);
@@ -113,6 +121,7 @@ public:
Q_SIGNALS:
void autoLoadImagesChanged();
void pluginsEnabledChanged();
+ void fullScreenEnabledChanged();
void javascriptEnabledChanged();
void offlineWebApplicationCacheEnabledChanged();
void localStorageEnabledChanged();
@@ -121,6 +130,7 @@ Q_SIGNALS:
void dnsPrefetchEnabledChanged();
void navigatorQtObjectEnabledChanged();
void frameFlatteningEnabledChanged();
+ void developerExtrasEnabledChanged();
void standardFontFamilyChanged();
void fixedFontFamilyChanged();
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h
index f4ef13c21..ae636c1c7 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h
@@ -29,6 +29,7 @@ public:
enum WebAttribute {
AutoLoadImages,
+ FullScreenEnabled,
JavascriptEnabled,
PluginsEnabled,
OfflineWebApplicationCacheEnabled,
@@ -36,7 +37,8 @@ public:
XSSAuditingEnabled,
FrameFlatteningEnabled,
PrivateBrowsingEnabled,
- DnsPrefetchEnabled
+ DnsPrefetchEnabled,
+ DeveloperExtrasEnabled
};
enum FontFamily {
@@ -59,6 +61,7 @@ public:
void setAttribute(WebAttribute attr, bool enable);
bool testAttribute(WebAttribute attr) const;
+ void initializeDefaultFontSettings();
void setFontFamily(FontFamily which, const QString& family);
QString fontFamily(FontFamily which) const;
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp
index 22863be29..170604d1d 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp
@@ -19,21 +19,22 @@
*/
#include "config.h"
+#include "QtViewportInteractionEngine.h"
#include "qwebviewportinfo_p.h"
#include "qquickwebview_p.h"
#include "qquickwebview_p_p.h"
+using namespace WebKit;
+
QWebViewportInfo::QWebViewportInfo(QQuickWebViewPrivate* webViewPrivate, QObject* parent)
: QObject(parent)
, m_webViewPrivate(webViewPrivate)
{
-
}
QWebViewportInfo::~QWebViewportInfo()
{
-
}
QSize QWebViewportInfo::contentsSize() const
@@ -46,55 +47,37 @@ QVariant QWebViewportInfo::currentScale() const
if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
return interactionEngine->currentCSSScale();
- return QtViewportInteractionEngine::Constraints().initialScale;
+ return m_webViewPrivate->attributes.initialScale;
}
QVariant QWebViewportInfo::devicePixelRatio() const
{
- if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
- return interactionEngine->constraints().devicePixelRatio;
-
- return QtViewportInteractionEngine::Constraints().devicePixelRatio;
+ return m_webViewPrivate->attributes.devicePixelRatio;
}
QVariant QWebViewportInfo::initialScale() const
{
- if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
- return interactionEngine->constraints().initialScale;
-
- return QtViewportInteractionEngine::Constraints().initialScale;
+ return m_webViewPrivate->attributes.initialScale;
}
QVariant QWebViewportInfo::minimumScale() const
{
- if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
- return interactionEngine->constraints().minimumScale;
-
- return QtViewportInteractionEngine::Constraints().minimumScale;
+ return m_webViewPrivate->attributes.minimumScale;
}
QVariant QWebViewportInfo::maximumScale() const
{
- if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
- return interactionEngine->constraints().maximumScale;
-
- return QtViewportInteractionEngine::Constraints().maximumScale;
+ return m_webViewPrivate->attributes.maximumScale;
}
QVariant QWebViewportInfo::isScalable() const
{
- if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
- return interactionEngine->constraints().isUserScalable;
-
- return QtViewportInteractionEngine::Constraints().isUserScalable;
+ return !!m_webViewPrivate->attributes.userScalable;
}
QVariant QWebViewportInfo::layoutSize() const
{
- if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine())
- return interactionEngine->constraints().layoutSize;
-
- return QVariant(QSize());
+ return QSizeF(m_webViewPrivate->attributes.layoutSize.width(), m_webViewPrivate->attributes.layoutSize.height());
}
void QWebViewportInfo::didUpdateContentsSize()
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.cpp b/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.cpp
index e0c2c256c..b81c07610 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.cpp
@@ -31,6 +31,10 @@ ByteArrayTestData::ByteArrayTestData(QObject* parent)
Q_ASSERT(m_latin1Data != m_utf8Data);
}
+ByteArrayTestData::~ByteArrayTestData()
+{
+}
+
QVariant ByteArrayTestData::latin1Data() const
{
return QVariant(m_latin1Data);
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.h b/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.h
index f7838f072..7f87e72dd 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.h
+++ b/Source/WebKit2/UIProcess/API/qt/tests/bytearraytestdata.h
@@ -33,7 +33,7 @@ class QWEBKIT_EXPORT ByteArrayTestData : public QObject {
public:
ByteArrayTestData(QObject* parent = 0);
- virtual ~ByteArrayTestData() { }
+ virtual ~ByteArrayTestData();
QVariant latin1Data() const;
QVariant utf8Data() const;
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html b/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html
index b4eea41bd..53726e4a6 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html
+++ b/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html
@@ -1 +1,6 @@
+<html>
+<head>
+<title> Basic Page </title>
+</head>
<h1>Basic page</h1>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/inputmethod.html b/Source/WebKit2/UIProcess/API/qt/tests/html/inputmethod.html
new file mode 100644
index 000000000..f3ca937d2
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/html/inputmethod.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Basic Page For Input Method Testing</title>
+</head>
+<body>
+<h1>Basic page</h1>
+<input id="inputField" />
+</body>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/inspectorserver.pro b/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/inspectorserver.pro
new file mode 100644
index 000000000..4a8d86f80
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/inspectorserver.pro
@@ -0,0 +1,4 @@
+include(../tests.pri)
+SOURCES += $${TARGET}.cpp
+QT += webkit-private
+DEFINES += IMPORT_DIR=\"\\\"$${ROOT_BUILD_DIR}$${QMAKE_DIR_SEP}imports\\\"\"
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp b/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp
new file mode 100644
index 000000000..0d0bb6902
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp
@@ -0,0 +1,183 @@
+/*
+ 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 "../testwindow.h"
+#include "../util.h"
+
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QScopedPointer>
+#include <QtQml/QQmlEngine>
+#include <QtTest/QtTest>
+#include <private/qquickwebview_p.h>
+#include <private/qwebpreferences_p.h>
+
+#define INSPECTOR_SERVER_PORT "23654"
+static const QUrl s_inspectorServerHttpBaseUrl("http://localhost:"INSPECTOR_SERVER_PORT);
+static const QUrl s_inspectorServerWebSocketBaseUrl("ws://localhost:"INSPECTOR_SERVER_PORT);
+
+class tst_InspectorServer : public QObject {
+ Q_OBJECT
+public:
+ tst_InspectorServer();
+
+private slots:
+ void init();
+ void cleanup();
+
+ void testPageList();
+ void testRemoteDebuggingMessage();
+ void openRemoteDebuggingSession();
+private:
+ void prepareWebViewComponent();
+ inline QQuickWebView* newWebView();
+ inline QQuickWebView* webView() const;
+ QJsonArray fetchPageList() const;
+ QScopedPointer<TestWindow> m_window;
+ QScopedPointer<QQmlComponent> m_component;
+};
+
+tst_InspectorServer::tst_InspectorServer()
+{
+ qputenv("QTWEBKIT_INSPECTOR_SERVER", INSPECTOR_SERVER_PORT);
+ addQtWebProcessToPath();
+ prepareWebViewComponent();
+}
+
+void tst_InspectorServer::prepareWebViewComponent()
+{
+ static QQmlEngine* engine = new QQmlEngine(this);
+ engine->addImportPath(QString::fromUtf8(IMPORT_DIR));
+
+ m_component.reset(new QQmlComponent(engine, this));
+
+ m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n"
+ "import QtWebKit 3.0\n"
+ "WebView {}")
+ , QUrl());
+}
+
+QQuickWebView* tst_InspectorServer::newWebView()
+{
+ QObject* viewInstance = m_component->create();
+
+ return qobject_cast<QQuickWebView*>(viewInstance);
+}
+
+void tst_InspectorServer::init()
+{
+ m_window.reset(new TestWindow(newWebView()));
+ webView()->experimental()->preferences()->setDeveloperExtrasEnabled(true);
+}
+
+void tst_InspectorServer::cleanup()
+{
+ m_window.reset();
+}
+
+inline QQuickWebView* tst_InspectorServer::webView() const
+{
+ return static_cast<QQuickWebView*>(m_window->webView.data());
+}
+
+QJsonArray tst_InspectorServer::fetchPageList() const
+{
+ QNetworkAccessManager qnam;
+ QScopedPointer<QNetworkReply> reply(qnam.get(QNetworkRequest(s_inspectorServerHttpBaseUrl.resolved(QUrl("pagelist.json")))));
+ waitForSignal(reply.data(), SIGNAL(finished()));
+ return QJsonDocument::fromJson(reply->readAll()).array();
+}
+
+void tst_InspectorServer::testPageList()
+{
+ QUrl testPageUrl = QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"));
+ LoadStartedCatcher catcher(webView());
+ webView()->setUrl(testPageUrl);
+ waitForSignal(&catcher, SIGNAL(finished()));
+
+ // Our page has developerExtrasEnabled and should be the only one in the list.
+ QJsonArray pageList = fetchPageList();
+ QCOMPARE(pageList.size(), 1);
+ QCOMPARE(testPageUrl.toString(), pageList.at(0).toObject().value("url").toString());
+}
+
+void tst_InspectorServer::testRemoteDebuggingMessage()
+{
+ QJsonArray pageList = fetchPageList();
+ QCOMPARE(pageList.size(), 1);
+
+ // Test sending a raw remote debugging message through our web socket server.
+ // For this specific message see: http://code.google.com/chrome/devtools/docs/protocol/tot/runtime.html#command-evaluate
+ QLatin1String jsExpression("2 + 2");
+ QLatin1String jsExpressionResult("4");
+ QScopedPointer<QQuickWebView> webSocketQueryWebView(newWebView());
+ webSocketQueryWebView->loadHtml(QString(
+ "<script type=\"text/javascript\">\n"
+ "var socket = new WebSocket('%1/devtools/page/%2');\n"
+ "socket.onmessage = function(message) {\n"
+ "var response = JSON.parse(message.data);\n"
+ "if (response.id === 1)\n"
+ "document.title = response.result.result.value;\n"
+ "}\n"
+ "socket.onopen = function() {\n"
+ "socket.send('{\"id\": 1, \"method\": \"Runtime.evaluate\", \"params\": {\"expression\": \"%3\" } }');\n"
+ "}\n"
+ "</script>")
+ .arg(s_inspectorServerWebSocketBaseUrl.toString())
+ .arg(pageList.at(0).toObject().value("id").toDouble())
+ .arg(jsExpression));
+
+ for (int i = 0; i < 10; ++i) {
+ if (!webSocketQueryWebView->title().isEmpty())
+ break;
+ waitForSignal(webSocketQueryWebView.data(), SIGNAL(titleChanged()), 500);
+ }
+
+ QCOMPARE(webSocketQueryWebView->title(), jsExpressionResult);
+}
+
+void tst_InspectorServer::openRemoteDebuggingSession()
+{
+ QJsonArray pageList = fetchPageList();
+ QCOMPARE(pageList.size(), 1);
+
+ QScopedPointer<QQuickWebView> inspectorWebView(newWebView());
+ LoadStartedCatcher catcher2(inspectorWebView.data());
+ inspectorWebView->setUrl(s_inspectorServerHttpBaseUrl.resolved(QUrl(pageList.at(0).toObject().value("inspectorUrl").toString())));
+ waitForSignal(&catcher2, SIGNAL(finished()));
+ for (int i = 0; i < 10; ++i) {
+ if (!inspectorWebView->title().isEmpty())
+ break;
+ waitForSignal(inspectorWebView.data(), SIGNAL(titleChanged()), 500);
+ }
+
+ // To test the whole pipeline this exploits a behavior of the inspector front-end which won't provide any title unless the
+ // debugging session was established correctly through web socket. It should be something like "Web Inspector - <Page URL>".
+ // So this test case will fail if:
+ // - The page list didn't return a valid inspector URL
+ // - Or the front-end couldn't be loaded through the inspector HTTP server
+ // - Or the web socket connection couldn't be established between the front-end and the page through the inspector server
+ // Let's see if this test isn't raising too many false positives, in which case we should use a better predicate if available.
+ QVERIFY(!inspectorWebView->title().isEmpty());
+}
+
+QTEST_MAIN(tst_InspectorServer)
+
+#include "tst_inspectorserver.moc"
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 f5f976663..39e6b54cf 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp
@@ -141,7 +141,11 @@ static void gatherAPI(const QString& prefix, const QMetaMethod& method, QStringL
{
if (method.access() != QMetaMethod::Private) {
const char* methodTypeName = !!strlen(method.typeName()) ? method.typeName() : "void";
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ *output << QString::fromLatin1("%1%2 --> %3").arg(prefix).arg(QString::fromLatin1(method.methodSignature())).arg(QString::fromLatin1(methodTypeName));
+#else
*output << QString::fromLatin1("%1%2 --> %3").arg(prefix).arg(method.signature()).arg(methodTypeName);
+#endif
checkKnownType(methodTypeName);
foreach (QByteArray paramType, method.parameterTypes())
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro
index 9d16a7bdd..59a3ca5b4 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro
@@ -19,4 +19,6 @@ OTHER_FILES += \
DesktopBehavior/tst_linkHovered.qml \
DesktopBehavior/tst_loadHtml.qml \
DesktopBehavior/tst_messaging.qml \
- DesktopBehavior/tst_navigationRequested.qml
+ DesktopBehavior/tst_navigationRequested.qml \
+ DesktopBehavior/tst_singleFileupload.qml \
+ DesktopBehavior/tst_multiFileupload.qml
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml
new file mode 100644
index 000000000..f43f65672
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml
@@ -0,0 +1,66 @@
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+import "../common"
+
+// FIXME: Added to Desktop tests because we want to have mouseClick() to open the <input> tag. We can move it back
+// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083.
+TestWebView {
+ id: webView
+
+ width: 400
+ height: 400
+
+ property bool selectFile
+
+ experimental.filePicker: Item {
+ Timer {
+ running: true
+ interval: 1
+ onTriggered: {
+ var selectedFiles = ["filename1", "filename2"]
+ if (selectFile)
+ model.accept(selectedFiles)
+ else
+ model.reject();
+ }
+ }
+ }
+
+ SignalSpy {
+ id: titleSpy
+ target: webView
+ signalName: "titleChanged"
+ }
+
+ TestCase {
+ id: test
+ name: "WebViewMultiFilePicker"
+ when: windowShown
+
+ function init() {
+ webView.url = Qt.resolvedUrl("../common/multifileupload.html")
+ verify(webView.waitForLoadSucceeded())
+ titleSpy.clear()
+ }
+
+ function openItemSelector() {
+ mouseClick(webView, 15, 15, Qt.LeftButton)
+ }
+
+ function test_accept() {
+ webView.selectFile = true;
+ openItemSelector()
+ titleSpy.wait()
+ compare(webView.title, "filename1,filename2")
+ }
+
+ function test_reject() {
+ var oldTitle = webView.title
+ webView.selectFile = false;
+ openItemSelector()
+ compare(webView.title, oldTitle)
+ }
+ }
+}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml
new file mode 100644
index 000000000..7ca9efa38
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml
@@ -0,0 +1,79 @@
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+import "../common"
+
+// FIXME: Added to Desktop tests because we want to have mouseClick() to open the <input> tag. We can move it back
+// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083.
+TestWebView {
+ id: webView
+
+ width: 400
+ height: 400
+
+ property bool selectFile
+ property bool acceptMultiple: false
+
+ experimental.filePicker: Item {
+ Timer {
+ running: true
+ interval: 1
+ onTriggered: {
+ var selectedFiles = ["filename1", "filename2"]
+ if (selectFile) {
+ if (acceptMultiple)
+ model.accept(selectedFiles)
+ else
+ model.accept("acceptedfilename");
+ }
+ else
+ model.reject();
+ }
+ }
+ }
+
+ SignalSpy {
+ id: titleSpy
+ target: webView
+ signalName: "titleChanged"
+ }
+
+ TestCase {
+ id: test
+ name: "WebViewSingleFilePicker"
+ when: windowShown
+
+ function init() {
+ webView.url = Qt.resolvedUrl("../common/singlefileupload.html")
+ verify(webView.waitForLoadSucceeded())
+ titleSpy.clear()
+ }
+
+ function openItemSelector() {
+ mouseClick(webView, 15, 15, Qt.LeftButton)
+ }
+
+ function test_accept() {
+ webView.selectFile = true;
+ openItemSelector()
+ titleSpy.wait()
+ compare(webView.title, "acceptedfilename")
+ }
+
+ function test_multiple() {
+ webView.selectFile = true;
+ webView.acceptMultiple = true;
+ openItemSelector()
+ titleSpy.wait()
+ compare(webView.title, "filename1")
+ }
+
+ function test_reject() {
+ var oldTitle = webView.title
+ webView.selectFile = false;
+ openItemSelector()
+ compare(webView.title, oldTitle)
+ }
+ }
+}
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 875bcd060..4fe081298 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
@@ -3,8 +3,9 @@ import QtTest 1.0
import QtWebKit 3.0
import QtWebKit.experimental 1.0
import Test 1.0
+import "../common"
-WebView {
+TestWebView {
id: webView
width: 400
height: 300
@@ -61,12 +62,6 @@ WebView {
]
}
- SignalSpy {
- id: spyTitle
- target: webView
- signalName: "titleChanged"
- }
-
ByteArrayTestData {
id: byteArrayHelper
}
@@ -75,58 +70,47 @@ WebView {
name: "WebViewApplicationSchemes"
function test_applicationScheme() {
- spyTitle.clear()
- compare(spyTitle.count, 0)
var testUrl = "applicationScheme://something"
webView.url = testUrl
- spyTitle.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Test Application Scheme")
}
function test_multipleSchemes() {
// Test if we receive the right reply when defining multiple schemes.
- spyTitle.clear()
- compare(spyTitle.count, 0)
var testUrl = "scheme2://some-url-string"
webView.url = testUrl
- spyTitle.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Scheme2 Reply")
testUrl = "scheme1://some-url-string"
webView.url = testUrl
- spyTitle.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Scheme1 Reply")
-
- compare(spyTitle.count, 2)
}
function test_multipleUrlsForScheme() {
- spyTitle.clear()
- compare(spyTitle.count, 0)
var testUrl = "scheme3://url1"
- webView.url = testUrl
- spyTitle.wait()
+ webView.url = testUrl
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Scheme3 Reply1")
testUrl = "scheme3://url2"
- webView.url = testUrl
- spyTitle.wait()
+ webView.url = testUrl
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Scheme3 Reply2")
- compare(spyTitle.count, 2)
}
- function test_charsets() {
- spyTitle.clear()
- compare(spyTitle.count, 0)
+ function test_charsets() {
var testUrl = "schemeCharset://latin1"
webView.url = testUrl
- spyTitle.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "title with copyright ©")
testUrl = "schemeCharset://utf-8"
webView.url = testUrl
- spyTitle.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "title with copyright ©")
}
}
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 8fcbae54a..7ab69bd15 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
@@ -13,7 +13,7 @@ TestWebView {
onLoadProgressChanged: {
if (watchProgress && webView.loadProgress != 100) {
watchProgress = false
- load('')
+ url = ''
}
}
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 4f356e88b..16ff35c52 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
@@ -198,8 +198,10 @@ Item {
function test_standardFontFamilyChanged() {
var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-family")
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, defaultStandardFontFamily)
@@ -207,8 +209,10 @@ Item {
standardFontFamilySpy.wait()
compare(standardFontFamilySpy.count, 1)
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, "foobar")
}
@@ -216,8 +220,10 @@ Item {
function test_fontSizeChanged() {
var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size")
webView.url = url
- titleSpy.wait()
- compare(webView.title, "Original Title")
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, defaultFontSize.toString() + "px")
@@ -225,8 +231,10 @@ Item {
defaultFontSizeSpy.wait()
compare(defaultFontSizeSpy.count, 1)
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, (defaultFontSize + 1).toString() + "px")
}
@@ -234,8 +242,10 @@ Item {
function test_fixedFontSizeChanged() {
var url = Qt.resolvedUrl("../common/font-preferences.html?fixed#font-size")
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, defaultFixedFontSize.toString() + "px")
@@ -243,14 +253,18 @@ Item {
defaultFixedFontSizeSpy.wait()
compare(defaultFixedFontSizeSpy.count, 1)
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, (defaultFixedFontSize + 1).toString() + "px")
webView.url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size")
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, defaultFontSize.toString() + "px")
}
@@ -259,8 +273,10 @@ Item {
verify(defaultMinimumFontSize < defaultFontSize)
var url = Qt.resolvedUrl("../common/font-preferences.html?minimum#font-size")
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
var smallerFontSize = webView.title
smallerFontSize = smallerFontSize.substring(0, smallerFontSize.length - 2)
@@ -271,8 +287,10 @@ Item {
minimumFontSizeSpy.wait()
compare(minimumFontSizeSpy.count, 1)
webView.url = url
- titleSpy.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Original Title")
+ titleSpy.clear()
+
titleSpy.wait()
compare(webView.title, defaultFontSize.toString() + "px")
}
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 04f2c7e13..38e587d57 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
@@ -21,9 +21,10 @@ TestWebView {
compare(spyTitle.count, 0)
var testUrl = Qt.resolvedUrl("../common/test3.html")
webView.url = testUrl
- verify(webView.waitForLoadSucceeded())
- spyTitle.wait()
+ verify(webView.waitForLoadSucceeded())
compare(webView.title, "Test page 3")
+ spyTitle.clear()
+
spyTitle.wait()
compare(webView.title, "New Title")
}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/multifileupload.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/multifileupload.html
new file mode 100644
index 000000000..7701ed4b5
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/multifileupload.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<meta name="viewport" initial-scale=1">
+<title> Mutli-file Upload </title>
+<script src = "./titleupdate.js">
+</script>
+
+<body>
+<input type="file" name="file" id="upfile" onchange="updateTitle()" multiple/>
+</body>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/singlefileupload.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/singlefileupload.html
new file mode 100644
index 000000000..38e345f4b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/singlefileupload.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<meta name="viewport" initial-scale=1">
+<title> Single File Upload </title>
+<script src = "./titleupdate.js">
+</script>
+
+<body>
+<input type="file" name="file" id="upfile" onchange="updateTitle()"/>
+</body>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/titleupdate.js b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/titleupdate.js
new file mode 100644
index 000000000..2a5bac0ac
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/titleupdate.js
@@ -0,0 +1,15 @@
+function updateTitle()
+{
+ var inp = document.getElementById("upfile");
+ var allfiles = new String("");
+ var name = new String("");
+ for (var i = 0; i < inp.files.length; ++i)
+ {
+ name = inp.files.item(i).name;
+ if (allfiles.length == 0)
+ allfiles = name;
+ else
+ allfiles = allfiles + "," + name;
+ }
+ document.title = allfiles;
+}
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 782b041ca..ab57556bd 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp
@@ -48,5 +48,5 @@ int main(int argc, char** argv)
#ifdef DISABLE_FLICKABLE_VIEWPORT
QQuickWebViewExperimental::setFlickableViewportEnabled(false);
#endif
- return quick_test_main(argc, argv, "qmltests", 0, QUICK_TEST_SOURCE_DIR);
+ return quick_test_main(argc, argv, "qmltests", QUICK_TEST_SOURCE_DIR);
}
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 a6b13990a..4d9ce7ba1 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp
@@ -20,12 +20,11 @@
#include "../testwindow.h"
#include "../util.h"
-#include <QDeclarativeEngine>
#include <QScopedPointer>
+#include <QtQml/QQmlEngine>
#include <QtTest/QtTest>
#include <private/qquickwebpage_p.h>
#include <private/qquickwebview_p.h>
-#include <private/qwebloadrequest_p.h>
class tst_QQuickWebView : public QObject {
Q_OBJECT
@@ -55,14 +54,18 @@ private slots:
void removeFromCanvas();
void multipleWebViewWindows();
void multipleWebViews();
+ void titleUpdate();
void transparentWebViews();
+ void inputMethod();
+
private:
void prepareWebViewComponent();
inline QQuickWebView* newWebView();
inline QQuickWebView* webView() const;
+ void runJavaScript(const QString& script);
QScopedPointer<TestWindow> m_window;
- QScopedPointer<QDeclarativeComponent> m_component;
+ QScopedPointer<QQmlComponent> m_component;
};
tst_QQuickWebView::tst_QQuickWebView()
@@ -73,10 +76,10 @@ tst_QQuickWebView::tst_QQuickWebView()
void tst_QQuickWebView::prepareWebViewComponent()
{
- static QDeclarativeEngine* engine = new QDeclarativeEngine(this);
+ static QQmlEngine* engine = new QQmlEngine(this);
engine->addImportPath(QString::fromUtf8(IMPORT_DIR));
- m_component.reset(new QDeclarativeComponent(engine, this));
+ m_component.reset(new QQmlComponent(engine, this));
m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n"
"import QtWebKit 3.0\n"
@@ -87,8 +90,9 @@ void tst_QQuickWebView::prepareWebViewComponent()
QQuickWebView* tst_QQuickWebView::newWebView()
{
QObject* viewInstance = m_component->create();
-
- return qobject_cast<QQuickWebView*>(viewInstance);
+ QQuickWebView* webView = qobject_cast<QQuickWebView*>(viewInstance);
+ webView->experimental()->setDevicePixelRatio(1.5);
+ return webView;
}
void tst_QQuickWebView::init()
@@ -106,6 +110,13 @@ inline QQuickWebView* tst_QQuickWebView::webView() const
return static_cast<QQuickWebView*>(m_window->webView.data());
}
+void tst_QQuickWebView::runJavaScript(const QString &script)
+{
+ QEventLoop loop;
+ webView()->runJavaScriptInMainFrame(script, &loop, "quit");
+ loop.exec();
+}
+
void tst_QQuickWebView::accessPage()
{
QQuickWebPage* const pageDirectAccess = webView()->page();
@@ -124,32 +135,6 @@ void tst_QQuickWebView::navigationStatusAtStartup()
QCOMPARE(webView()->loading(), false);
}
-class LoadStartedCatcher : public QObject {
- Q_OBJECT
-public:
- LoadStartedCatcher(QQuickWebView* webView)
- : m_webView(webView)
- {
- connect(m_webView, SIGNAL(loadingChanged(QWebLoadRequest*)), this, SLOT(onLoadingChanged(QWebLoadRequest*)));
- }
-
-public slots:
- void onLoadingChanged(QWebLoadRequest* loadRequest)
- {
- if (loadRequest->status() == QQuickWebView::LoadStartedStatus) {
- QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
-
- QCOMPARE(m_webView->loading(), true);
- }
- }
-
-signals:
- void finished();
-
-private:
- QQuickWebView* m_webView;
-};
-
void tst_QQuickWebView::stopEnabledAfterLoadStarted()
{
QCOMPARE(webView()->loading(), false);
@@ -344,6 +329,24 @@ void tst_QQuickWebView::multipleWebViews()
QTest::qWait(200);
}
+void tst_QQuickWebView::titleUpdate()
+{
+ QSignalSpy titleSpy(webView(), SIGNAL(titleChanged()));
+
+ // Load page with no title
+ webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")));
+ QVERIFY(waitForLoadSucceeded(webView()));
+ QCOMPARE(titleSpy.size(), 1);
+
+ titleSpy.clear();
+
+ // No titleChanged signal for failed load
+ webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html")));
+ QVERIFY(waitForLoadFailed(webView()));
+ QCOMPARE(titleSpy.size(), 0);
+
+}
+
void tst_QQuickWebView::transparentWebViews()
{
showWebView();
@@ -371,6 +374,19 @@ void tst_QQuickWebView::transparentWebViews()
// FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609.
}
+void tst_QQuickWebView::inputMethod()
+{
+ QQuickWebView* view = webView();
+ view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/inputmethod.html")));
+ QVERIFY(waitForLoadSucceeded(view));
+
+ QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+ runJavaScript("document.getElementById('inputField').focus();");
+ QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+ runJavaScript("document.getElementById('inputField').blur();");
+ QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+}
+
void tst_QQuickWebView::scrollRequest()
{
webView()->setSize(QSizeF(300, 400));
@@ -382,7 +398,7 @@ void tst_QQuickWebView::scrollRequest()
// Use qRound as that is also used when calculating the position
// in WebKit.
int y = qRound(50 * webView()->page()->contentsScale());
- QVERIFY(webView()->experimental()->contentY() == y);
+ QVERIFY(webView()->contentY() == y);
}
QTEST_MAIN(tst_QQuickWebView)
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri
index aa8da8bc9..ded493f88 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri
+++ b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri
@@ -3,13 +3,14 @@ TEMPLATE = app
VPATH += $$_PRO_FILE_PWD_
TARGET = tst_$$TARGET
-HEADERS += ../bytearraytestdata.h
+HEADERS += ../bytearraytestdata.h \
+ ../util.h
SOURCES += ../util.cpp \
../bytearraytestdata.cpp
INCLUDEPATH += $$PWD
-QT += testlib declarative quick webkit
+QT += testlib declarative quick quick-private 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 43a6696ef..2582848aa 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/util.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp
@@ -20,6 +20,7 @@
#include "util.h"
#include "private/qquickwebview_p.h"
#include "private/qwebloadrequest_p.h"
+#include <QtTest/QtTest>
#include <stdio.h>
void addQtWebProcessToPath()
@@ -120,4 +121,20 @@ void suppressDebugOutput()
qputenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT", "1");
}
+
+LoadStartedCatcher::LoadStartedCatcher(QQuickWebView* webView)
+ : m_webView(webView)
+{
+ connect(m_webView, SIGNAL(loadingChanged(QWebLoadRequest*)), this, SLOT(onLoadingChanged(QWebLoadRequest*)));
+}
+
+void LoadStartedCatcher::onLoadingChanged(QWebLoadRequest* loadRequest)
+{
+ if (loadRequest->status() == QQuickWebView::LoadStartedStatus) {
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+
+ QCOMPARE(m_webView->loading(), true);
+ }
+}
+
#include "util.moc"
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.h b/Source/WebKit2/UIProcess/API/qt/tests/util.h
index f7be8b11e..9d076f1b4 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/util.h
+++ b/Source/WebKit2/UIProcess/API/qt/tests/util.h
@@ -23,6 +23,7 @@
#include <QTimer>
class QQuickWebView;
+class QWebLoadRequest;
#if !defined(TESTS_SOURCE_DIR)
#define TESTS_SOURCE_DIR ""
@@ -33,3 +34,15 @@ 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();
+
+class LoadStartedCatcher : public QObject {
+ Q_OBJECT
+public:
+ LoadStartedCatcher(QQuickWebView* webView);
+public slots:
+ void onLoadingChanged(QWebLoadRequest* loadRequest);
+signals:
+ void finished();
+private:
+ QQuickWebView* m_webView;
+};