Implement the Web Share API
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Aug 2018 00:20:26 +0000 (00:20 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Aug 2018 00:20:26 +0000 (00:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171100
<rdar://problem/31751734>

Patch by Olivia Barnett <obarnett@apple.com> on 2018-08-29
Reviewed by Tim Horton.

LayoutTests/imported/w3c:

* web-platform-tests/web-share/idlharness.https-expected.txt:
* web-platform-tests/web-share/share-empty.https-expected.txt:
* web-platform-tests/web-share/share-securecontext.http-expected.txt:
* web-platform-tests/web-share/share-url-invalid.https-expected.txt:
* web-platform-tests/web-share/share-without-user-gesture.https-expected.txt:
Updated expected results.

Source/WebCore:

Added one test in fast/events/ios called share.html; adjusted expectations for existing tests.

* DerivedSources.make:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* features.json:
* loader/EmptyClients.cpp:
(WebCore::EmptyChromeClient::showShareSheet):
* loader/EmptyClients.h:
Added empty showShareSheet function.

* page/Chrome.cpp:
(WebCore::Chrome::showShareSheet):
* page/Chrome.h:
Added call to showShareSheet on client.

* page/ChromeClient.h:
Virtual showShareSheet function.

* page/Navigator.cpp:
(WebCore::Navigator::share):
* page/Navigator.h:
Share function that returns a promise and invokes the share sheet.

* page/Navigator.idl:
Implements NavigatorShare

* page/NavigatorShare.idl: Added.
Added definition of share function returning a promise.

* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::setWebShareEnabled):
(WebCore::RuntimeEnabledFeatures::webShareEnabled const):
Added RuntimeEnabledFeature switch.

* page/ShareData.h: Added.
* page/ShareData.idl: Added.
Definition of ShareData struct.

Source/WebKit:

* Platform/spi/ios/UIKitSPI.h:
Added NSURL _title property as in the WebCore UIKitSPI.

* Scripts/webkit/messages.py:
ShareDataWithParsedURL special case for header for type.

* Shared/ShareSheetCallbackID.h:
Added a typedef for a share sheet callback id.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ShareData>::encode):
(IPC::ArgumentCoder<ShareData>::decode):
(IPC::ArgumentCoder<ShareDataWithParsedURL>::encode):
(IPC::ArgumentCoder<ShareDataWithParsedURL>::decode):
* Shared/WebCoreArgumentCoders.h:
Added encoding and decoding functionality for new structs.

* Shared/WebPreferences.yaml:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetWebShareEnabled):
(WKPreferencesGetWebShareEnabled):
* UIProcess/API/C/WKPreferencesRefPrivate.h:
Added switch for RuntimeEnabledFeature.

* UIProcess/API/Cocoa/WKWebView.mm:
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
Added hook for share sheet testing.

* UIProcess/PageClient.h:
(WebKit::PageClient::showShareSheet):
Page client call to invoke share sheet.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::showShareSheet):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
Web page proxy handling of call to invoke share sheet.
Creates completion handler to send to WKShareSheet.mm
Completion handler sends message to WebPage with message id.

* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::showShareSheet):
Page client implementation call to invoke share sheet.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView cleanupInteraction]):
(-[WKContentView _showShareSheet:completionHandler:]):
(-[WKContentView shareSheetDidDismiss:]):
(-[WKContentView invokeShareSheetWithResolution:resolved):
Call to WKShareSheet to invoke the share sheet and callback.
Hook for share sheet resolution testing.

* UIProcess/ios/forms/WKShareSheet.h: Added.
* UIProcess/ios/forms/WKShareSheet.mm: Added.
(-[WKShareSheet initWithView:]):
(-[WKShareSheet presentWithParameters:completionHandler:]):
(-[WKShareSheet _dispatchDidDismiss]):
(-[WKShareSheet _cancel]):
(-[WKShareSheet dismiss]):
(-[WKShareSheet _dismissDisplayAnimated:]):
(-[WKShareSheet _presentFullscreenViewController:animated:]):
(-[WKShareSheet invokeShareSheetWithResolution:resolved:]):
Completion handler call and creation of share sheet with parameters.
Hook that force resolves the share sheet completion handler for testing.

* WebKit.xcodeproj/project.pbxproj:

* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::showShareSheet):
Call to page to invoke share sheet.

* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::nextShareSheetContextId):
(WebKit::WebPage::showShareSheet):
(WebKit::WebPage::showShareSheetResponse):
WebPage calls proxy and saves context id for promise.

* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
Callback for completed response.

Source/WebKitLegacy/ios:

* WebCoreSupport/WebChromeClientIOS.h:
* WebCoreSupport/WebChromeClientIOS.mm:
(WebChromeClientIOS::showShareSheet):
Empty declaration of showShareSheet.

Source/WebKitLegacy/mac:

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::showShareSheet):
Empty declaration of showShareSheet.

LayoutTests:

* fast/dom/navigator-detached-no-crash-expected.txt:
Updated expected results.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235489 268f45cc-cd09-0410-ab3c-d52691b4dbfc

68 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/navigator-detached-no-crash-expected.txt
LayoutTests/fast/events/ios/share-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/share.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/idlharness.https-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-empty.https-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-securecontext.http-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-url-invalid.https-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-without-user-gesture.https-expected.txt [new file with mode: 0644]
LayoutTests/resources/ui-helper.js
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.make
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/features.json
Source/WebCore/loader/EmptyClients.cpp
Source/WebCore/loader/EmptyClients.h
Source/WebCore/page/Chrome.cpp
Source/WebCore/page/Chrome.h
Source/WebCore/page/ChromeClient.h
Source/WebCore/page/Navigator.cpp
Source/WebCore/page/Navigator.h
Source/WebCore/page/Navigator.idl
Source/WebCore/page/NavigatorShare.idl [new file with mode: 0644]
Source/WebCore/page/RuntimeEnabledFeatures.h
Source/WebCore/page/ShareData.h [new file with mode: 0644]
Source/WebCore/page/ShareData.idl [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/Platform/spi/ios/UIKitSPI.h
Source/WebKit/Scripts/webkit/messages.py
Source/WebKit/Shared/ShareSheetCallbackID.h [new file with mode: 0644]
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/Shared/WebPreferencesDefaultValues.h
Source/WebKit/UIProcess/API/C/WKPreferences.cpp
Source/WebKit/UIProcess/API/C/WKPreferencesRefPrivate.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/UIProcess/ios/PageClientImplIOS.h
Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit/UIProcess/ios/forms/WKShareSheet.h [new file with mode: 0644]
Source/WebKit/UIProcess/ios/forms/WKShareSheet.mm [new file with mode: 0644]
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKitLegacy/ios/ChangeLog
Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.h
Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm
Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index 9a0aa24..cba248c 100644 (file)
@@ -1,3 +1,14 @@
+2018-08-29  Olivia Barnett  <obarnett@apple.com>
+
+        Implement the Web Share API
+        https://bugs.webkit.org/show_bug.cgi?id=171100
+        <rdar://problem/31751734>
+
+        Reviewed by Tim Horton.
+
+        * fast/dom/navigator-detached-no-crash-expected.txt:
+        Updated expected results.
+
 2018-08-29  Ryan Haddad  <ryanhaddad@apple.com>
 
         Layout Test js/error-should-not-strong-reference-global-object.html is flaky on macOS
index 333ec96..d9f644f 100644 (file)
@@ -1,4 +1,5 @@
 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments
+CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments
 This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 
  Check Navigator
 navigator.appCodeName is OK
@@ -20,6 +21,8 @@ navigator.productSub is OK
 navigator.requestMediaKeySystemAccess() is OK
 navigator.sendBeacon() threw err TypeError: Not enough arguments
 navigator.serviceWorker is OK
+navigator.share() is OK
+navigator.standalone is OK
 navigator.userAgent is OK
 navigator.vendor is OK
 navigator.vendorSub is OK
@@ -43,6 +46,8 @@ navigator.productSub is OK
 navigator.requestMediaKeySystemAccess() is OK
 navigator.sendBeacon() threw err TypeError: Not enough arguments
 navigator.serviceWorker is OK
+navigator.share() is OK
+navigator.standalone is OK
 navigator.userAgent is OK
 navigator.vendor is OK
 navigator.vendorSub is OK
diff --git a/LayoutTests/fast/events/ios/share-expected.txt b/LayoutTests/fast/events/ios/share-expected.txt
new file mode 100644 (file)
index 0000000..c67d83e
--- /dev/null
@@ -0,0 +1,2 @@
+PASS: Share sheet invoked.
+
diff --git a/LayoutTests/fast/events/ios/share.html b/LayoutTests/fast/events/ios/share.html
new file mode 100644 (file)
index 0000000..982ca8f
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<meta name="viewport" content="initial-scale=5, width=device-width">
+<head>
+
+    <script src="../../../resources/ui-helper.js"></script>
+    <script>
+        
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+    
+        let write = (message) => output.innerHTML += (message + "<br>");
+
+        async function runTest()
+        {
+            document.getElementById("target").addEventListener("click", async () => {
+                navigator.share({ title: "Example Page", url: "url", text: "text" }).then((result) => {
+                    write("PASS: Share sheet invoked.");
+                    testRunner.notifyDone();
+                });
+                UIHelper.invokeShareSheetWithResolution(true);
+            });
+            await UIHelper.activateAt(50, 50);
+        }
+
+    </script>
+    <style>
+        #target {
+            height: 100px;
+            width: 100px;
+            background-color: silver;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+<pre id="output"></pre>
+<button id="target">
+</button>
+
+</body>
+</html>
+
index 01426a1..6e1e1cb 100644 (file)
@@ -1,3 +1,18 @@
+2018-08-29  Olivia Barnett  <obarnett@apple.com>
+
+        Implement the Web Share API
+        https://bugs.webkit.org/show_bug.cgi?id=171100
+        <rdar://problem/31751734>
+
+        Reviewed by Tim Horton.
+
+        * web-platform-tests/web-share/idlharness.https-expected.txt:
+        * web-platform-tests/web-share/share-empty.https-expected.txt:
+        * web-platform-tests/web-share/share-securecontext.http-expected.txt:
+        * web-platform-tests/web-share/share-url-invalid.https-expected.txt:
+        * web-platform-tests/web-share/share-without-user-gesture.https-expected.txt:
+        Updated expected results.
+
 2018-08-29  Youenn Fablet  <youenn@apple.com>
 
         Remove WebRTC legacy API implementation
diff --git a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/idlharness.https-expected.txt b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/idlharness.https-expected.txt
new file mode 100644 (file)
index 0000000..2fff230
--- /dev/null
@@ -0,0 +1,7 @@
+
+PASS Test driver 
+PASS Navigator interface: operation share(ShareData) 
+PASS Unscopable handled correctly for share(ShareData) on Navigator 
+PASS Navigator interface: navigator must inherit property "share(ShareData)" with the proper type 
+PASS Navigator interface: calling share(ShareData) on navigator with too few arguments must throw TypeError 
+
diff --git a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-empty.https-expected.txt b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-empty.https-expected.txt
new file mode 100644 (file)
index 0000000..57d3291
--- /dev/null
@@ -0,0 +1,7 @@
+
+PASS share with no arguments (same as empty dictionary) 
+PASS share with an empty dictionary 
+PASS share with a undefined argument (same as empty dictionary) 
+PASS share with a null argument (same as empty dictionary) 
+PASS share with a dictionary containing only surplus fields 
+
diff --git a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-securecontext.http-expected.txt b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-securecontext.http-expected.txt
new file mode 100644 (file)
index 0000000..b39bcda
--- /dev/null
@@ -0,0 +1,3 @@
+
+FAIL navigator.share must be undefined in non-secure context assert_false: navigator has attribute 'share'. expected false got true
+
diff --git a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-url-invalid.https-expected.txt b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-url-invalid.https-expected.txt
new file mode 100644 (file)
index 0000000..0e90442
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS share with an invalid URL 
+
diff --git a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-without-user-gesture.https-expected.txt b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/web-share/share-without-user-gesture.https-expected.txt
new file mode 100644 (file)
index 0000000..1ddfa67
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS share without a user gesture 
+
index 7ed42c4..d53c1fd 100644 (file)
@@ -262,6 +262,12 @@ window.UIHelper = class UIHelper {
         return new Promise(resolve => testRunner.runUIScript(setValueScript, resolve));
     }
 
+    static invokeShareSheetWithResolution(resolved)
+    {
+        const resolveShareSheet = `(() => uiController.invokeShareSheetWithResolution(${resolved}))()`;
+        return new Promise(resolve => testRunner.runUIScript(resolveShareSheet, resolve));
+    }
+
     static textContentType()
     {
         return new Promise(resolve => {
index 4d9e61d..cd78931 100644 (file)
@@ -811,6 +811,7 @@ set(WebCore_NON_SVG_IDL_FILES
     page/NavigatorLanguage.idl
     page/NavigatorOnLine.idl
     page/NavigatorServiceWorker.idl
+    page/NavigatorShare.idl
     page/Performance.idl
     page/PerformanceEntry.idl
     page/PerformanceMark.idl
@@ -825,6 +826,7 @@ set(WebCore_NON_SVG_IDL_FILES
     page/RemoteDOMWindow.idl
     page/Screen.idl
     page/ScrollToOptions.idl
+    page/ShareData.idl
     page/VisualViewport.idl
     page/WebKitPoint.idl
     page/WindowEventHandlers.idl
index d0d34b3..2de1f59 100644 (file)
@@ -1,3 +1,50 @@
+2018-08-29  Olivia Barnett  <obarnett@apple.com>
+
+        Implement the Web Share API
+        https://bugs.webkit.org/show_bug.cgi?id=171100
+        <rdar://problem/31751734>
+
+        Reviewed by Tim Horton.
+
+        Added one test in fast/events/ios called share.html; adjusted expectations for existing tests.
+
+        * DerivedSources.make:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * features.json:
+        * loader/EmptyClients.cpp:
+        (WebCore::EmptyChromeClient::showShareSheet):
+        * loader/EmptyClients.h:
+        Added empty showShareSheet function.
+
+        * page/Chrome.cpp:
+        (WebCore::Chrome::showShareSheet):
+        * page/Chrome.h:
+        Added call to showShareSheet on client.
+
+        * page/ChromeClient.h:
+        Virtual showShareSheet function.
+
+        * page/Navigator.cpp:
+        (WebCore::Navigator::share):
+        * page/Navigator.h:
+        Share function that returns a promise and invokes the share sheet.
+
+        * page/Navigator.idl:
+        Implements NavigatorShare
+
+        * page/NavigatorShare.idl: Added.
+        Added definition of share function returning a promise.
+
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::setWebShareEnabled):
+        (WebCore::RuntimeEnabledFeatures::webShareEnabled const):
+        Added RuntimeEnabledFeature switch.
+
+        * page/ShareData.h: Added.
+        * page/ShareData.idl: Added.
+        Definition of ShareData struct.
+
 2018-08-29  Daniel Bates  <dabates@apple.com>
 
         REGRESSION (r226138): WebCore::subdivide() may return an empty vector; Web process can crash when performing find in Epiphany
index b77ddbf..a5fdb3e 100644 (file)
@@ -774,6 +774,8 @@ JS_BINDING_IDLS = \
     $(WebCore)/page/NavigatorID.idl \
     $(WebCore)/page/NavigatorLanguage.idl \
     $(WebCore)/page/NavigatorOnLine.idl \
+    $(WebCore)/page/NavigatorShare.idl \
+    $(WebCore)/page/ShareData.idl \
     $(WebCore)/page/NavigatorServiceWorker.idl \
     $(WebCore)/page/Performance.idl \
     $(WebCore)/page/PerformanceEntry.idl \
index e67ac10..aaf936e 100644 (file)
@@ -2782,6 +2782,8 @@ JSNavigatorLanguage.cpp
 JSNavigatorMediaCapabilities.cpp
 JSNavigatorMediaDevices.cpp
 JSNavigatorOnLine.cpp
+JSNavigatorShare.cpp
+JSShareData.cpp
 JSNavigatorServiceWorker.cpp
 JSNavigatorWebDriver.cpp
 JSNavigatorWebVR.cpp
index b9122d6..20e2892 100644 (file)
                1CAF34830A6C405200ABE06E /* WebScriptObjectPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF34800A6C405200ABE06E /* WebScriptObjectPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1CCDF5BE1990332400BCEBAD /* SVGToOTFFontConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CCDF5BC1990332400BCEBAD /* SVGToOTFFontConversion.h */; };
                1CFAE3230A6D6A3F0032593D /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CFAE3220A6D6A3F0032593D /* libobjc.dylib */; };
+               1D9F0FC12122029B005D8FD4 /* ShareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC55400211BA8C8004B780E /* ShareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1F36EA9C1E21BA1700621E25 /* WebBackgroundTaskController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F36EA9A1E21BA1700621E25 /* WebBackgroundTaskController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1F3C3BEB135CAF3C00B8C1AC /* MediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3C3BE9135CAF3C00B8C1AC /* MediaControls.h */; };
                1F72BF0B187FD45C0009BCB3 /* TileControllerMemoryHandlerIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F72BF09187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1CDD45E50BA9C84600F90147 /* WebCore.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebCore.xcconfig; sourceTree = "<group>"; };
                1CDD45E60BA9C84600F90147 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
                1CFAE3220A6D6A3F0032593D /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
+               1DC553FD211BA12A004B780E /* NavigatorShare.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorShare.idl; sourceTree = "<group>"; };
+               1DC553FF211BA841004B780E /* ShareData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ShareData.idl; sourceTree = "<group>"; };
+               1DC55400211BA8C8004B780E /* ShareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareData.h; sourceTree = "<group>"; };
                1F36EA9A1E21BA1700621E25 /* WebBackgroundTaskController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebBackgroundTaskController.h; sourceTree = "<group>"; };
                1F36EA9B1E21BA1700621E25 /* WebBackgroundTaskController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebBackgroundTaskController.mm; sourceTree = "<group>"; };
                1F3C3BE8135CAF3C00B8C1AC /* MediaControls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControls.cpp; sourceTree = "<group>"; };
                                7C5BEA3B1E9EE77100CC517B /* NavigatorLanguage.idl */,
                                7C5BEA3C1E9EE77100CC517B /* NavigatorOnLine.idl */,
                                5182C24B1F313AE00059BA7C /* NavigatorServiceWorker.idl */,
+                               1DC553FD211BA12A004B780E /* NavigatorShare.idl */,
                                00146288103CD1DE000B20DB /* OriginAccessEntry.cpp */,
                                00146289103CD1DE000B20DB /* OriginAccessEntry.h */,
                                65FEA86809833ADE00BED4AB /* Page.cpp */,
                                7CC6609B1F93057900D500E9 /* SettingsBase.cpp */,
                                7CC660991F93057800D500E9 /* SettingsBase.h */,
                                7C6EFEEA1F946A2E00FFAD41 /* SettingsDefaultValues.h */,
+                               1DC55400211BA8C8004B780E /* ShareData.h */,
+                               1DC553FF211BA841004B780E /* ShareData.idl */,
                                5C688AA21D38126F000B54FA /* SocketProvider.cpp */,
                                5C7C88D71D0F1F2B009D2F6D /* SocketProvider.h */,
                                626CDE0C1140424C001E5A68 /* SpatialNavigation.cpp */,
                                FD45A95B175D41EE00C21EC8 /* ShapeInterval.h in Headers */,
                                FD45A952175D3F3E00C21EC8 /* ShapeOutsideInfo.h in Headers */,
                                FD1AF1501656F15100C6D4F7 /* ShapeValue.h in Headers */,
+                               1D9F0FC12122029B005D8FD4 /* ShareData.h in Headers */,
                                1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */,
                                834DFAD01F7DAE5D00C2725B /* SharedStringHash.h in Headers */,
                                93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */,
index 16a73ec..2ece761 100644 (file)
     {
         "name": "Web Share",
         "status": {
-            "status": "Under Consideration"
+            "status": "In Development"
         },
         "url": "https://github.com/WICG/web-share/blob/master/docs/interface.md",
         "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=171100",
index d4b915d..cad4bd8 100644 (file)
@@ -436,6 +436,10 @@ std::unique_ptr<DataListSuggestionPicker> EmptyChromeClient::createDataListSugge
 void EmptyChromeClient::runOpenPanel(Frame&, FileChooser&)
 {
 }
+    
+void EmptyChromeClient::showShareSheet(ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&)
+{
+}
 
 PAL::SessionID EmptyFrameLoaderClient::sessionID() const
 {
index 9d052b0..d83ffd9 100644 (file)
@@ -137,6 +137,7 @@ class EmptyChromeClient : public ChromeClient {
 #endif
 
     void runOpenPanel(Frame&, FileChooser&) final;
+    void showShareSheet(ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&) final;
     void loadIconForFiles(const Vector<String>&, FileIconLoader&) final { }
 
     void elementDidFocus(Element&) final { }
index 1331cb1..aedd4b4 100644 (file)
@@ -46,6 +46,7 @@
 #include "RenderObject.h"
 #include "ResourceHandle.h"
 #include "Settings.h"
+#include "ShareData.h"
 #include "StorageNamespace.h"
 #include "WindowFeatures.h"
 #include <JavaScriptCore/VM.h>
@@ -449,6 +450,11 @@ void Chrome::runOpenPanel(Frame& frame, FileChooser& fileChooser)
     m_client.runOpenPanel(frame, fileChooser);
 }
 
+void Chrome::showShareSheet(ShareDataWithParsedURL& shareData, CompletionHandler<void(bool)>&& callback)
+{
+    m_client.showShareSheet(shareData, WTFMove(callback));
+}
+
 void Chrome::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader)
 {
     m_client.loadIconForFiles(filenames, loader);
index ccbce93..4db7099 100644 (file)
@@ -59,6 +59,7 @@ class PopupOpeningObserver;
 class SearchPopupMenu;
 
 struct DateTimeChooserParameters;
+struct ShareDataWithParsedURL;
 struct ViewportArguments;
 struct WindowFeatures;
     
@@ -159,6 +160,7 @@ public:
 #endif
 
     void runOpenPanel(Frame&, FileChooser&);
+    void showShareSheet(ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&);
     void loadIconForFiles(const Vector<String>&, FileIconLoader&);
 
     void dispatchDisabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>&) const;
index 472b618..9c3b7cc 100644 (file)
@@ -101,6 +101,7 @@ class MediaPlayerRequestInstallMissingPluginsCallback;
 
 struct DateTimeChooserParameters;
 struct GraphicsDeviceAdapter;
+struct ShareDataWithParsedURL;
 struct ViewportArguments;
 struct WindowFeatures;
 
@@ -282,6 +283,8 @@ public:
 #endif
 
     virtual void runOpenPanel(Frame&, FileChooser&) = 0;
+    virtual void showShareSheet(ShareDataWithParsedURL&, WTF::CompletionHandler<void(bool)>&& callback) { callback(false); }
+    
     // Asynchronous request to load an icon for specified filenames.
     virtual void loadIconForFiles(const Vector<String>&, FileIconLoader&) = 0;
         
index 7809800..2aef7a9 100644 (file)
@@ -23,6 +23,7 @@
 #include "config.h"
 #include "Navigator.h"
 
+#include "Chrome.h"
 #include "CookieJar.h"
 #include "DOMMimeTypeArray.h"
 #include "DOMPluginArray.h"
@@ -31,6 +32,7 @@
 #include "FrameLoader.h"
 #include "FrameLoaderClient.h"
 #include "Geolocation.h"
+#include "JSDOMPromiseDeferred.h"
 #include "LoaderStrategy.h"
 #include "Page.h"
 #include "PlatformStrategies.h"
@@ -40,6 +42,7 @@
 #include "Settings.h"
 #include <wtf/Language.h>
 #include <wtf/StdLibExtras.h>
+#include <wtf/WeakPtr.h>
 
 
 namespace WebCore {
@@ -94,6 +97,43 @@ bool Navigator::onLine() const
     return platformStrategies()->loaderStrategy()->isOnLine();
 }
 
+void Navigator::share(ScriptExecutionContext& context, ShareData data, Ref<DeferredPromise>&& promise)
+{
+    if (!m_frame->page()) {
+        promise->reject(TypeError);
+        return;
+    }
+    
+    if (data.title.isEmpty() && data.url.isEmpty() && data.text.isEmpty()) {
+        promise->reject(TypeError);
+        return;
+    }
+    
+    URL url = context.completeURL(data.url);
+    if (!url.isValid()) {
+        promise->reject(TypeError);
+        return;
+    }
+    
+    if (!UserGestureIndicator::processingUserGesture()) {
+        promise->reject(NotAllowedError);
+        return;
+    }
+    
+    ShareDataWithParsedURL shareData = {
+        data,
+        url,
+    };
+
+    m_frame->page()->chrome().showShareSheet(shareData, [promise = WTFMove(promise)] (bool completed) {
+        if (completed) {
+            promise->resolve();
+            return;
+        }
+        promise->reject(Exception { AbortError, "Abort due to cancellation of share."_s });
+    });
+}
+
 DOMPluginArray& Navigator::plugins()
 {
     if (!m_plugins)
index b86ed89..bd260df 100644 (file)
 #pragma once
 
 #include "DOMWindowProperty.h"
+#include "JSDOMPromiseDeferred.h"
 #include "NavigatorBase.h"
 #include "ScriptWrappable.h"
+#include "ShareData.h"
 #include "Supplementable.h"
 
 namespace WebCore {
@@ -42,6 +44,7 @@ public:
     const String& userAgent() const final;
     void userAgentChanged();
     bool onLine() const final;
+    void share(ScriptExecutionContext&, ShareData, Ref<DeferredPromise>&&);
     
 #if PLATFORM(IOS)
     bool standalone() const;
index b37eda9..69d55c8 100644 (file)
@@ -35,4 +35,4 @@ Navigator implements NavigatorID;
 Navigator implements NavigatorLanguage;
 Navigator implements NavigatorOnLine;
 Navigator implements NavigatorServiceWorker;
-
+Navigator implements NavigatorShare;
diff --git a/Source/WebCore/page/NavigatorShare.idl b/Source/WebCore/page/NavigatorShare.idl
new file mode 100644 (file)
index 0000000..4157db8
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* Copyright (C) 2018 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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
+* 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.
+*/
+
+
+[
+    NoInterfaceObject,
+    EnabledAtRuntime=WebShare
+] interface NavigatorShare {
+    [CallWith=ScriptExecutionContext, SecureContext] Promise<void> share(optional ShareData shareData);
+};
index a60d8a3..bc83f8a 100644 (file)
@@ -86,6 +86,9 @@ public:
 
     void setCustomPasteboardDataEnabled(bool isEnabled) { m_isCustomPasteboardDataEnabled = isEnabled; }
     bool customPasteboardDataEnabled() const { return m_isCustomPasteboardDataEnabled; }
+    
+    void setWebShareEnabled(bool isEnabled) { m_isWebShareEnabled = isEnabled; }
+    bool webShareEnabled() const { return m_isWebShareEnabled; }
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     void setAttachmentElementEnabled(bool areEnabled) { m_isAttachmentElementEnabled = areEnabled; }
@@ -304,6 +307,7 @@ private:
     bool m_isDirectoryUploadEnabled { false };
     bool m_areDataTransferItemsEnabled { false };
     bool m_isCustomPasteboardDataEnabled { false };
+    bool m_isWebShareEnabled { false };
     bool m_inputEventsEnabled { true };
 
 #if ENABLE(ATTACHMENT_ELEMENT)
diff --git a/Source/WebCore/page/ShareData.h b/Source/WebCore/page/ShareData.h
new file mode 100644 (file)
index 0000000..279f033
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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
+ * 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.
+ */
+
+#pragma once
+#include "URL.h"
+
+namespace WebCore {
+    
+struct ShareData {
+    String title;
+    String text;
+    String url;
+};
+    
+struct ShareDataWithParsedURL {
+    ShareData shareData;
+    URL url;
+};
+    
+}
diff --git a/Source/WebCore/page/ShareData.idl b/Source/WebCore/page/ShareData.idl
new file mode 100644 (file)
index 0000000..1f5b00b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+* Copyright (C) 2018 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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
+* 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.
+*/
+
+dictionary ShareData {
+    USVString title;
+    USVString text;
+    USVString url;
+};
index 439ed38..00de170 100644 (file)
@@ -1,3 +1,95 @@
+2018-08-29  Olivia Barnett  <obarnett@apple.com>
+
+        Implement the Web Share API
+        https://bugs.webkit.org/show_bug.cgi?id=171100
+        <rdar://problem/31751734>
+
+        Reviewed by Tim Horton.
+
+        * Platform/spi/ios/UIKitSPI.h:
+        Added NSURL _title property as in the WebCore UIKitSPI.
+
+        * Scripts/webkit/messages.py:
+        ShareDataWithParsedURL special case for header for type.
+        
+        * Shared/ShareSheetCallbackID.h:
+        Added a typedef for a share sheet callback id.       
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ShareData>::encode):
+        (IPC::ArgumentCoder<ShareData>::decode):
+        (IPC::ArgumentCoder<ShareDataWithParsedURL>::encode):
+        (IPC::ArgumentCoder<ShareDataWithParsedURL>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        Added encoding and decoding functionality for new structs.
+
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetWebShareEnabled):
+        (WKPreferencesGetWebShareEnabled):
+        * UIProcess/API/C/WKPreferencesRefPrivate.h:
+        Added switch for RuntimeEnabledFeature.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        Added hook for share sheet testing.
+
+        * UIProcess/PageClient.h:
+        (WebKit::PageClient::showShareSheet):
+        Page client call to invoke share sheet.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::showShareSheet):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        Web page proxy handling of call to invoke share sheet.
+        Creates completion handler to send to WKShareSheet.mm
+        Completion handler sends message to WebPage with message id.
+
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::showShareSheet):
+        Page client implementation call to invoke share sheet. 
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView cleanupInteraction]):
+        (-[WKContentView _showShareSheet:completionHandler:]):
+        (-[WKContentView shareSheetDidDismiss:]):
+        (-[WKContentView invokeShareSheetWithResolution:resolved):
+        Call to WKShareSheet to invoke the share sheet and callback.
+        Hook for share sheet resolution testing.
+
+        * UIProcess/ios/forms/WKShareSheet.h: Added.
+        * UIProcess/ios/forms/WKShareSheet.mm: Added.
+        (-[WKShareSheet initWithView:]):
+        (-[WKShareSheet presentWithParameters:completionHandler:]):
+        (-[WKShareSheet _dispatchDidDismiss]):
+        (-[WKShareSheet _cancel]):
+        (-[WKShareSheet dismiss]):
+        (-[WKShareSheet _dismissDisplayAnimated:]):
+        (-[WKShareSheet _presentFullscreenViewController:animated:]):
+        (-[WKShareSheet invokeShareSheetWithResolution:resolved:]):
+        Completion handler call and creation of share sheet with parameters.
+        Hook that force resolves the share sheet completion handler for testing. 
+
+        * WebKit.xcodeproj/project.pbxproj:
+
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::showShareSheet):
+        Call to page to invoke share sheet.
+
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::nextShareSheetContextId):
+        (WebKit::WebPage::showShareSheet):
+        (WebKit::WebPage::showShareSheetResponse):
+        WebPage calls proxy and saves context id for promise.        
+
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        Callback for completed response.
+
 2018-08-29  Chris Dumez  <cdumez@apple.com>
 
         Crash under WebKit: WTF::Function<void ()>::CallableWrapper<WebKit::ResourceLoadStatisticsMemoryStore::removeDataRecords(WTF::CompletionHandler<void ()>&&)::$_1>::call()
index 2874908..a8857ab 100644 (file)
@@ -418,12 +418,17 @@ typedef enum {
 @property (readonly) NSString *_hostApplicationBundleIdentifier;
 @end
 
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
+@interface NSURL ()
+@property (nonatomic, copy, setter=_setTitle:) NSString *_title;
+@end
+#endif
+
 @protocol UIViewControllerContextTransitioningEx <UIViewControllerContextTransitioning>
 - (void)__runAlongsideAnimations;
 - (void)_interactivityDidChange:(BOOL)isInteractive;
 @property (nonatomic, assign, setter=_setAllowUserInteraction:, getter=_allowUserInteraction) BOOL _allowUserInteraction;
 @property (nonatomic, assign, setter=_setPercentOffset:) CGFloat _percentOffset;
-@property (nonatomic, retain, setter=_setContainerViews:) NSArray *_containerViews;
 @end
 
 @interface _UIViewControllerTransitionContext : NSObject <UIViewControllerContextTransitioningEx>
index 06bea1c..9ac3728 100644 (file)
@@ -380,6 +380,7 @@ def headers_for_type(type):
         'WebCore::AutoplayEventFlags': ['<WebCore/AutoplayEvent.h>'],
         'WebCore::ExceptionDetails': ['<WebCore/JSDOMExceptionHandling.h>'],
         'WebCore::FileChooserSettings': ['<WebCore/FileChooser.h>'],
+        'WebCore::ShareDataWithParsedURL': ['<WebCore/ShareData.h>'],
         'WebCore::FrameLoadType': ['<WebCore/FrameLoaderTypes.h>'],
         'WebCore::GrammarDetail': ['<WebCore/TextCheckerClient.h>'],
         'WebCore::HasInsecureContent': ['<WebCore/FrameLoaderTypes.h>'],
diff --git a/Source/WebKit/Shared/ShareSheetCallbackID.h b/Source/WebKit/Shared/ShareSheetCallbackID.h
new file mode 100644 (file)
index 0000000..b57baa2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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
+ * 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.
+ */
+
+
+typedef uint64_t ShareSheetCallbackID;
+
index f44438f..9dab37d 100644 (file)
@@ -71,6 +71,7 @@
 #include <WebCore/ServiceWorkerClientData.h>
 #include <WebCore/ServiceWorkerClientIdentifier.h>
 #include <WebCore/ServiceWorkerData.h>
+#include <WebCore/ShareData.h>
 #include <WebCore/TextCheckerClient.h>
 #include <WebCore/TextIndicator.h>
 #include <WebCore/TimingFunction.h>
@@ -1916,7 +1917,39 @@ bool ArgumentCoder<FileChooserSettings>::decode(Decoder& decoder, FileChooserSet
 
     return true;
 }
+    
+void ArgumentCoder<ShareData>::encode(Encoder& encoder, const ShareData& settings)
+{
+    encoder << settings.title;
+    encoder << settings.text;
+    encoder << settings.url;
+}
+
+bool ArgumentCoder<ShareData>::decode(Decoder& decoder, ShareData& settings)
+{
+    if (!decoder.decode(settings.title))
+        return false;
+    if (!decoder.decode(settings.text))
+        return false;
+    if (!decoder.decode(settings.url))
+        return false;
+    return true;
+}
+    
+void ArgumentCoder<ShareDataWithParsedURL>::encode(Encoder& encoder, const ShareDataWithParsedURL& settings)
+{
+    encoder << settings.shareData;
+    encoder << settings.url;
+}
 
+bool ArgumentCoder<ShareDataWithParsedURL>::decode(Decoder& decoder, ShareDataWithParsedURL& settings)
+{
+    if (!decoder.decode(settings.shareData))
+        return false;
+    if (!decoder.decode(settings.url))
+        return false;
+    return true;
+}
 
 void ArgumentCoder<GrammarDetail>::encode(Encoder& encoder, const GrammarDetail& detail)
 {
index 8ca760f..f1b1395 100644 (file)
@@ -102,6 +102,8 @@ struct DictionaryPopupInfo;
 struct EventTrackingRegions;
 struct ExceptionDetails;
 struct FileChooserSettings;
+struct ShareData;
+struct ShareDataWithParsedURL;
 struct Length;
 struct GrammarDetail;
 struct MimeClassInfo;
@@ -474,6 +476,16 @@ template<> struct ArgumentCoder<WebCore::FileChooserSettings> {
     static void encode(Encoder&, const WebCore::FileChooserSettings&);
     static bool decode(Decoder&, WebCore::FileChooserSettings&);
 };
+    
+template<> struct ArgumentCoder<WebCore::ShareData> {
+    static void encode(Encoder&, const WebCore::ShareData&);
+    static bool decode(Decoder&, WebCore::ShareData&);
+};
+    
+template<> struct ArgumentCoder<WebCore::ShareDataWithParsedURL> {
+    static void encode(Encoder&, const WebCore::ShareDataWithParsedURL&);
+    static bool decode(Decoder&, WebCore::ShareDataWithParsedURL&);
+};
 
 template<> struct ArgumentCoder<WebCore::GrammarDetail> {
     static void encode(Encoder&, const WebCore::GrammarDetail&);
index 1f41929..10f49ba 100644 (file)
@@ -766,6 +766,13 @@ CustomPasteboardDataEnabled:
   humanReadableDescription: "Enable custom clipboard types and better security model for clipboard API."
   webcoreBinding: RuntimeEnabledFeatures
 
+WebShareEnabled:
+  type: bool
+  defaultValue: DEFAULT_WEB_SHARE_ENABLED
+  humanReadableName: "Web Share"
+  humanReadableDescription: "Enable support for share sheet via Web Share API"
+  webcoreBinding: RuntimeEnabledFeatures
+
 ViewportFitEnabled:
   type: bool
   defaultValue: true
index 47812b1..7398a24 100644 (file)
@@ -65,6 +65,7 @@
 #define DEFAULT_TEXT_AREAS_ARE_RESIZABLE false
 #define DEFAULT_JAVASCRIPT_CAN_OPEN_WINDOWS_AUTOMATICALLY false
 #define DEFAULT_SHOULD_RESPECT_IMAGE_ORIENTATION true
+#define DEFAULT_WEB_SHARE_ENABLED true
 #define DEFAULT_PASSWORD_ECHO_ENABLED true
 #define DEFAULT_ALLOWS_INLINE_MEDIA_PLAYBACK false
 #define DEFAULT_ALLOWS_INLINE_MEDIA_PLAYBACK_AFTER_FULLSCREEN true
@@ -84,6 +85,7 @@
 #define DEFAULT_TEXT_AREAS_ARE_RESIZABLE true
 #define DEFAULT_JAVASCRIPT_CAN_OPEN_WINDOWS_AUTOMATICALLY true
 #define DEFAULT_SHOULD_RESPECT_IMAGE_ORIENTATION false
+#define DEFAULT_WEB_SHARE_ENABLED false
 #define DEFAULT_PASSWORD_ECHO_ENABLED false
 #define DEFAULT_ALLOWS_INLINE_MEDIA_PLAYBACK true
 #define DEFAULT_ALLOWS_INLINE_MEDIA_PLAYBACK_AFTER_FULLSCREEN false
index 2b06b4c..cf73032 100644 (file)
@@ -1728,6 +1728,16 @@ bool WKPreferencesGetCustomPasteboardDataEnabled(WKPreferencesRef preferencesRef
     return toImpl(preferencesRef)->customPasteboardDataEnabled();
 }
 
+void WKPreferencesSetWebShareEnabled(WKPreferencesRef preferencesRef, bool flag)
+{
+    toImpl(preferencesRef)->setWebShareEnabled(flag);
+}
+
+bool WKPreferencesGetWebShareEnabled(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->webShareEnabled();
+}
+
 void WKPreferencesSetDownloadAttributeEnabled(WKPreferencesRef preferencesRef, bool flag)
 {
     toImpl(preferencesRef)->setDownloadAttributeEnabled(flag);
index 7cd4825..862a045 100644 (file)
@@ -496,6 +496,10 @@ WK_EXPORT bool WKPreferencesGetDataTransferItemsEnabled(WKPreferencesRef);
 // Defaults to false
 WK_EXPORT void WKPreferencesSetCustomPasteboardDataEnabled(WKPreferencesRef, bool flag);
 WK_EXPORT bool WKPreferencesGetCustomPasteboardDataEnabled(WKPreferencesRef);
+    
+// Defaults to false, true for iOS
+WK_EXPORT void WKPreferencesSetWebShareEnabled(WKPreferencesRef, bool flag);
+WK_EXPORT bool WKPreferencesGetWebShareEnabled(WKPreferencesRef);
 
 // Defaults to false
 WK_EXPORT void WKPreferencesSetUserTimingEnabled(WKPreferencesRef, bool flag);
index e5f40f7..dbc5243 100644 (file)
@@ -5933,6 +5933,11 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe
     [_contentView setTimePickerValueToHour:hour minute:minute];
 }
 
+- (void)_invokeShareSheetWithResolution:(BOOL)resolved
+{
+    [_contentView invokeShareSheetWithResolution:resolved];
+}
+
 - (void)selectFormAccessoryPickerRow:(int)rowIndex
 {
     [_contentView selectFormAccessoryPickerRow:rowIndex];
index f050eb0..6d1cb1d 100644 (file)
@@ -382,6 +382,8 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 @property (nonatomic, readonly) NSString *formInputLabel WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)setTimePickerValueToHour:(NSInteger)hour minute:(NSInteger)minute WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
+- (void)_invokeShareSheetWithResolution:(BOOL)resolved WK_API_AVAILABLE(ios(WK_IOS_TBA));
+
 - (void)applyAutocorrection:(NSString *)newString toString:(NSString *)oldString withCompletionHandler:(void (^)(void))completionHandler WK_API_AVAILABLE(ios(11.0));
 
 - (void)didStartFormControlInteraction WK_API_AVAILABLE(ios(10.3));
index 04c8115..bb09d1d 100644 (file)
@@ -80,6 +80,7 @@ struct DictionaryPopupInfo;
 struct Highlight;
 struct TextIndicatorData;
 struct ViewportAttributes;
+struct ShareDataWithParsedURL;
 
 template <typename> class RectEdges;
 using FloatBoxExtent = RectEdges<float>;
@@ -201,6 +202,7 @@ public:
     virtual void handleDownloadRequest(DownloadProxy*) = 0;
 
     virtual bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, API::OpenPanelParameters*, WebOpenPanelResultListenerProxy*) { return false; }
+    virtual bool showShareSheet(const WebCore::ShareDataWithParsedURL&, WTF::CompletionHandler<void (bool)>&&) { return false; }
 
     virtual void didChangeContentSize(const WebCore::IntSize&) = 0;
 
index 5262d33..fe4e329 100644 (file)
@@ -77,6 +77,7 @@
 #include "PluginProcessManager.h"
 #include "PrintInfo.h"
 #include "SafeBrowsingResult.h"
+#include "ShareSheetCallbackID.h"
 #include "TextChecker.h"
 #include "TextCheckerState.h"
 #include "UIMessagePortChannelProvider.h"
 #include <WebCore/ResourceLoadStatistics.h>
 #include <WebCore/SSLKeyGenerator.h>
 #include <WebCore/SerializedCryptoKeyWrap.h>
+#include <WebCore/ShareData.h>
 #include <WebCore/SharedBuffer.h>
 #include <WebCore/ShouldSkipSafeBrowsingCheck.h>
 #include <WebCore/ShouldTreatAsContinuingLoad.h>
@@ -4585,6 +4587,15 @@ void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& fram
     }
 }
 
+void WebPageProxy::showShareSheet(const ShareDataWithParsedURL& shareData, ShareSheetCallbackID callbackID)
+{
+    CompletionHandler<void(bool)> completionHandler = [this, protectedThis = makeRef(*this), callbackID] (bool access) {
+        m_process->send(Messages::WebPage::DidCompleteShareSheet(access, callbackID), m_pageID);
+    };
+    
+    m_pageClient.showShareSheet(shareData, WTFMove(completionHandler));
+}
+    
 void WebPageProxy::printFrame(uint64_t frameID)
 {
     ASSERT(!m_isPerformingDOMPrintOperation);
index 25fe4a2..da0581d 100644 (file)
@@ -43,6 +43,7 @@
 #include "ProcessTerminationReason.h"
 #include "ProcessThrottler.h"
 #include "SandboxExtension.h"
+#include "ShareSheetCallbackID.h"
 #include "ShareableBitmap.h"
 #include "SuspendedPageProxy.h"
 #include "SystemPreviewController.h"
@@ -187,6 +188,7 @@ struct FileChooserSettings;
 struct GlobalWindowIdentifier;
 struct MediaStreamRequest;
 struct SecurityOriginData;
+struct ShareData;
 struct TextAlternativeWithRange;
 struct TextCheckingResult;
 struct ViewportAttributes;
@@ -1468,6 +1470,7 @@ private:
     void didChangeViewportProperties(const WebCore::ViewportAttributes&);
     void pageDidScroll();
     void runOpenPanel(uint64_t frameID, const WebCore::SecurityOriginData&, const WebCore::FileChooserSettings&);
+    void showShareSheet(const WebCore::ShareDataWithParsedURL&, ShareSheetCallbackID);
     void printFrame(uint64_t frameID);
     void exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&&);
     void reachedApplicationCacheOriginQuota(const String& originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded, Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::DelayedReply&&);
index ed11e37..008dae7 100644 (file)
@@ -76,6 +76,7 @@ messages -> WebPageProxy {
     RunBeforeUnloadConfirmPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message) -> (bool shouldClose) Delayed
     PageDidScroll()
     RunOpenPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebCore::FileChooserSettings parameters)
+    ShowShareSheet(struct WebCore::ShareDataWithParsedURL shareData, uint64_t callbackID)
     PrintFrame(uint64_t frameID) -> ()
     RunModal()
     NotifyScrollerThumbIsVisibleInRect(WebCore::IntRect scrollerThumb)
index 13fbd29..a814b3d 100644 (file)
@@ -144,6 +144,8 @@ private:
     void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect, WebCore::RouteSharingPolicy, const String&) override;
 
     bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, API::OpenPanelParameters*, WebOpenPanelResultListenerProxy*) override;
+    bool showShareSheet(const WebCore::ShareDataWithParsedURL&, WTF::CompletionHandler<void(bool)>&&) override;
+    
     void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) override;
     double minimumZoomScale() const override;
     WebCore::FloatRect documentRect() const override;
index d79d0c2..847c9f0 100644 (file)
@@ -54,6 +54,7 @@
 #import <WebCore/NotImplemented.h>
 #import <WebCore/PlatformScreen.h>
 #import <WebCore/PromisedAttachmentInfo.h>
+#import <WebCore/ShareData.h>
 #import <WebCore/SharedBuffer.h>
 #import <WebCore/TextIndicator.h>
 #import <WebCore/ValidationBubble.h>
@@ -569,6 +570,12 @@ bool PageClientImpl::handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, API::Open
     return true;
 }
 
+bool PageClientImpl::showShareSheet(const ShareDataWithParsedURL& shareData, WTF::CompletionHandler<void(bool)>&& completionHandler)
+{
+    [m_contentView _showShareSheet:shareData completionHandler:WTFMove(completionHandler)];
+    return true;
+}
+
 void PageClientImpl::showInspectorHighlight(const WebCore::Highlight& highlight)
 {
     [m_contentView _showInspectorHighlight:highlight];
index bfa67be..6dc3eee 100644 (file)
@@ -38,6 +38,7 @@
 #import "WKFileUploadPanel.h"
 #import "WKFormPeripheral.h"
 #import "WKKeyboardScrollingAnimator.h"
+#import "WKShareSheet.h"
 #import "WKSyntheticClickTapGestureRecognizer.h"
 #import <UIKit/UIView.h>
 #import <WebCore/Color.h>
@@ -62,6 +63,7 @@ class FloatQuad;
 class IntSize;
 class SelectionRect;
 struct PromisedAttachmentInfo;
+struct ShareDataWithParsedURL;
 enum class RouteSharingPolicy;
 }
 
@@ -174,6 +176,7 @@ struct WKAutoCorrectionData {
 #endif
     RetainPtr<WKFormInputSession> _formInputSession;
     RetainPtr<WKFileUploadPanel> _fileUploadPanel;
+    RetainPtr<WKShareSheet> _shareSheet;
     RetainPtr<UIGestureRecognizer> _previewGestureRecognizer;
     RetainPtr<UIGestureRecognizer> _previewSecondaryGestureRecognizer;
     Vector<bool> _focusStateStack;
@@ -262,7 +265,7 @@ struct WKAutoCorrectionData {
 
 @end
 
-@interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UITextAutoscrolling, UITextInputMultiDocument, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWebTouchEventsGestureRecognizerDelegate, UIWKInteractionViewProtocol, WKActionSheetAssistantDelegate, WKFileUploadPanelDelegate, WKKeyboardScrollable
+@interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UITextAutoscrolling, UITextInputMultiDocument, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWebTouchEventsGestureRecognizerDelegate, UIWKInteractionViewProtocol, WKActionSheetAssistantDelegate, WKFileUploadPanelDelegate, WKShareSheetDelegate, WKKeyboardScrollable
 #if ENABLE(DATA_INTERACTION)
     , UIDragInteractionDelegate, UIDropInteractionDelegate
 #endif
@@ -317,6 +320,7 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
 - (void)_overflowScrollingDidEnd;
 - (void)_showPlaybackTargetPicker:(BOOL)hasVideo fromRect:(const WebCore::IntRect&)elementRect routeSharingPolicy:(WebCore::RouteSharingPolicy)policy routingContextUID:(NSString *)contextUID;
 - (void)_showRunOpenPanel:(API::OpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
+- (void)_showShareSheet:(const WebCore::ShareDataWithParsedURL&)shareData completionHandler:(WTF::CompletionHandler<void(bool)>&&)completionHandler;
 - (void)accessoryDone;
 - (void)_didHandleKeyEvent:(::WebEvent *)event eventWasHandled:(BOOL)eventWasHandled;
 - (Vector<WebKit::OptionItem>&) assistedNodeSelectOptions;
@@ -359,6 +363,7 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
 - (void)_simulateTextEntered:(NSString *)text;
 - (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex;
 - (void)setTimePickerValueToHour:(NSInteger)hour minute:(NSInteger)minute;
+- (void)invokeShareSheetWithResolution:(BOOL)resolved;
 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem;
 
 @property (nonatomic, readonly) NSString *textContentTypeForTesting;
index 216e59c..93ddc59 100644 (file)
@@ -84,6 +84,7 @@
 #import <WebCore/PromisedAttachmentInfo.h>
 #import <WebCore/RuntimeApplicationChecks.h>
 #import <WebCore/Scrollbar.h>
+#import <WebCore/ShareData.h>
 #import <WebCore/TextIndicator.h>
 #import <WebCore/VisibleSelection.h>
 #import <WebCore/WebCoreNSURLExtras.h>
@@ -779,6 +780,12 @@ static inline bool hasAssistedNode(WebKit::AssistedNodeInformation assistedNodeI
         _fileUploadPanel = nil;
     }
     
+    if (_shareSheet) {
+        [_shareSheet setDelegate:nil];
+        [_shareSheet dismiss];
+        _shareSheet = nil;
+    }
+    
     _inputViewUpdateDeferrer = nullptr;
     _assistedNodeInformation = { };
     
@@ -4693,6 +4700,18 @@ static bool isAssistableInputType(InputType type)
     [_fileUploadPanel presentWithParameters:parameters resultListener:listener];
 }
 
+- (void)_showShareSheet:(const ShareDataWithParsedURL&)data completionHandler:(CompletionHandler<void(bool)>&&)completionHandler
+{
+    ASSERT(!_shareSheet);
+    if (_shareSheet)
+        return;
+    
+    _shareSheet = adoptNS([[WKShareSheet alloc] initWithView:self]);
+    [_shareSheet setDelegate:self];
+    
+    [_shareSheet presentWithParameters:data completionHandler:WTFMove(completionHandler)];
+}
+
 - (void)fileUploadPanelDidDismiss:(WKFileUploadPanel *)fileUploadPanel
 {
     ASSERT(_fileUploadPanel.get() == fileUploadPanel);
@@ -4701,6 +4720,14 @@ static bool isAssistableInputType(InputType type)
     _fileUploadPanel = nil;
 }
 
+- (void)shareSheetDidDismiss:(WKShareSheet *)shareSheet
+{
+    ASSERT(_shareSheet == shareSheet);
+    
+    [_shareSheet setDelegate:nil];
+    _shareSheet = nil;
+}
+
 #pragma mark - UITextInputMultiDocument
 
 - (void)_restoreFocusWithToken:(id <NSCopying, NSSecureCoding>)token
@@ -5858,6 +5885,11 @@ static NSArray<UIItemProvider *> *extractItemProvidersFromDropSession(id <UIDrop
 #endif
 }
 
+- (void)invokeShareSheetWithResolution:(BOOL)resolved
+{
+    [_shareSheet invokeShareSheetWithResolution:resolved];
+}
+
 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
 {
     if ([userInterfaceItem isEqualToString:@"actionSheet"])
diff --git a/Source/WebKit/UIProcess/ios/forms/WKShareSheet.h b/Source/WebKit/UIProcess/ios/forms/WKShareSheet.h
new file mode 100644 (file)
index 0000000..c9a2402
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if PLATFORM(IOS)
+
+#import <UIKit/UIKit.h>
+#import <WebCore/ShareData.h>
+#import <wtf/BlockPtr.h>
+#import <wtf/Forward.h>
+#import <wtf/Vector.h>
+#import <wtf/WeakObjCPtr.h>
+#import <wtf/text/WTFString.h>
+
+@class WKContentView;
+@protocol WKShareSheetDelegate;
+
+@interface WKShareSheet : UIViewController
+- (instancetype)initWithView:(WKContentView *)view;
+
+- (void)presentWithParameters:(const WebCore::ShareDataWithParsedURL&)data completionHandler:(WTF::CompletionHandler<void(bool)>&&)completionHandler;
+- (void)dismiss;
+- (void)invokeShareSheetWithResolution:(BOOL)resolved;
+
+@property (nonatomic, weak) id <WKShareSheetDelegate> delegate;
+@end
+
+@protocol WKShareSheetDelegate <NSObject>
+@optional
+- (void)shareSheetDidDismiss:(WKShareSheet *)shareSheet;
+@end
+
+#endif // PLATFORM(IOS)
diff --git a/Source/WebKit/UIProcess/ios/forms/WKShareSheet.mm b/Source/WebKit/UIProcess/ios/forms/WKShareSheet.mm
new file mode 100644 (file)
index 0000000..0fa4baa
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "WKShareSheet.h"
+
+#if PLATFORM(IOS)
+
+#import "UIKitSPI.h"
+#import "WKContentViewInteraction.h"
+#import "WebPageProxy.h"
+#import <WebCore/ShareData.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/WeakObjCPtr.h>
+
+using namespace WebKit;
+
+@implementation WKShareSheet {
+    WeakObjCPtr<WKContentView> _view;
+
+    RetainPtr<UIActivityViewController> _shareSheetViewController;
+    RetainPtr<UIViewController> _presentationViewController;
+    BOOL _shouldDismissWithAnimation;
+}
+
+- (instancetype)initWithView:(WKContentView *)view
+{
+    if (!(self = [super init]))
+        return nil;
+    _view = view;
+    _shouldDismissWithAnimation = YES;
+    return self;
+}
+
+- (void)presentWithParameters:(const WebCore::ShareDataWithParsedURL &)data completionHandler:(WTF::CompletionHandler<void(bool)>&&)completionHandler
+{
+    auto shareDataArray = adoptNS([[NSMutableArray alloc] init]);
+    
+    if (!data.shareData.text.isEmpty())
+        [shareDataArray addObject:(NSString *)data.shareData.text];
+    
+    if (!data.url.isNull()) {
+        NSURL *url = (NSURL *)data.url;
+        if (!data.shareData.title.isEmpty())
+            url._title = data.shareData.title;
+        [shareDataArray addObject:url];
+    }
+    
+    if (!data.shareData.title.isEmpty() && ![shareDataArray count])
+        [shareDataArray addObject:(NSString *)data.shareData.title];
+    
+    auto shareSheetController = adoptNS([[UIActivityViewController alloc] initWithActivityItems:shareDataArray.get() applicationActivities:nil]);
+
+    auto completionHandlerBlock = BlockPtr<void((NSString *, BOOL completed, NSArray *, NSError *))>::fromCallable([completionHandler = WTFMove(completionHandler), shareSheet = self](NSString *, BOOL completed, NSArray *, NSError *) mutable {
+        completionHandler(completed);
+        [shareSheet dismiss];
+    });
+    
+    shareSheetController.get().completionWithItemsHandler = completionHandlerBlock.get();
+    _shareSheetViewController = WTFMove(shareSheetController);
+    [self _presentFullscreenViewController:_shareSheetViewController.get() animated:YES];
+}
+
+- (void)_dispatchDidDismiss
+{
+    if ([_delegate respondsToSelector:@selector(shareSheetDidDismiss:)])
+        [_delegate shareSheetDidDismiss:self];
+}
+
+- (void)_cancel
+{
+    [self _dispatchDidDismiss];
+}
+
+- (void)dismiss
+{
+    [[UIViewController _viewControllerForFullScreenPresentationFromView:_view.getAutoreleased()] dismissViewControllerAnimated:_shouldDismissWithAnimation completion:nil];
+    _presentationViewController = nil;
+    
+    [self _cancel];
+}
+
+- (void)_dismissDisplayAnimated:(BOOL)animated
+{
+    if (_presentationViewController) {
+        UIViewController *currentPresentedViewController = [_presentationViewController presentedViewController];
+        if (currentPresentedViewController == self) {
+            [currentPresentedViewController dismissViewControllerAnimated:animated completion:^{
+                _presentationViewController = nil;
+            }];
+        }
+    }
+}
+
+- (void)_presentFullscreenViewController:(UIViewController *)viewController animated:(BOOL)animated
+{
+    _presentationViewController = [UIViewController _viewControllerForFullScreenPresentationFromView:_view.getAutoreleased()];
+    [_presentationViewController presentViewController:viewController animated:animated completion:nil];
+}
+
+- (void)invokeShareSheetWithResolution:(BOOL)resolved
+{
+    _shouldDismissWithAnimation = NO;
+    _shareSheetViewController.get().completionWithItemsHandler(nil, resolved, nil, nil);
+}
+
+@end
+#endif // PLATFORM(IOS)
index 2f3dca8..94c9b1f 100644 (file)
                1CA8B946127C882A00576C2B /* WebInspectorProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CA8B944127C882A00576C2B /* WebInspectorProxyMessages.h */; };
                1CBBE4A019B66C53006B7D81 /* WebInspectorUIMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CBBE49E19B66C53006B7D81 /* WebInspectorUIMessageReceiver.cpp */; };
                1CBBE4A119B66C53006B7D81 /* WebInspectorUIMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CBBE49F19B66C53006B7D81 /* WebInspectorUIMessages.h */; };
+               1D67B339212E1F6100FAA786 /* ShareSheetCallbackID.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D67B338212E1F6100FAA786 /* ShareSheetCallbackID.h */; };
+               1DB01943211CF002009FB3E8 /* WKShareSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE0D095211CC21300439B5F /* WKShareSheet.h */; };
+               1DB01944211CF005009FB3E8 /* WKShareSheet.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1DBBB061211CC3CB00502ECC /* WKShareSheet.mm */; };
                1F335BC0185B84F0001A201A /* WKWebProcessPlugInLoadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F335BBF185B84D8001A201A /* WKWebProcessPlugInLoadDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1F604BAA1889FBB800EE0395 /* _WKRenderingProgressEventsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F604BA71889FA7400EE0395 /* _WKRenderingProgressEventsInternal.h */; };
                1F7506B11859163700EC0FF7 /* WKWebProcessPlugInFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0181691858DC1500F92884 /* WKWebProcessPlugInFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1CBBE49E19B66C53006B7D81 /* WebInspectorUIMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebInspectorUIMessageReceiver.cpp; sourceTree = "<group>"; };
                1CBBE49F19B66C53006B7D81 /* WebInspectorUIMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebInspectorUIMessages.h; sourceTree = "<group>"; };
                1CC417C912C00CCA002BE67B /* TextCheckerCompletion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCheckerCompletion.h; sourceTree = "<group>"; };
+               1D67B338212E1F6100FAA786 /* ShareSheetCallbackID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareSheetCallbackID.h; sourceTree = "<group>"; };
+               1DBBB061211CC3CB00502ECC /* WKShareSheet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKShareSheet.mm; path = ios/forms/WKShareSheet.mm; sourceTree = "<group>"; };
+               1DE0D095211CC21300439B5F /* WKShareSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKShareSheet.h; path = ios/forms/WKShareSheet.h; sourceTree = "<group>"; };
                1F0181691858DC1500F92884 /* WKWebProcessPlugInFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebProcessPlugInFrame.h; sourceTree = "<group>"; };
                1F01816A1858DC1500F92884 /* WKWebProcessPlugInFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebProcessPlugInFrame.mm; sourceTree = "<group>"; };
                1F01816B1858DC1500F92884 /* WKWebProcessPlugInFrameInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebProcessPlugInFrameInternal.h; sourceTree = "<group>"; };
                                8313F7E71F7DAE0300B944EB /* SharedStringHashTable.h */,
                                83F9644B1FA0F76200C47750 /* SharedStringHashTableReadOnly.cpp */,
                                83F9644C1FA0F76300C47750 /* SharedStringHashTableReadOnly.h */,
+                               1D67B338212E1F6100FAA786 /* ShareSheetCallbackID.h */,
                                5272B2881406985D0096A5D0 /* StatisticsData.cpp */,
                                5272B2891406985D0096A5D0 /* StatisticsData.h */,
                                1A5E4DA312D3BD3D0099A2BB /* TextCheckerState.h */,
                                F4D5F51C206087A10038BBA8 /* WKQuickboardListViewController.mm */,
                                F4F59AD42065A5CA006CAA46 /* WKSelectMenuListViewController.h */,
                                F4F59AD32065A5C9006CAA46 /* WKSelectMenuListViewController.mm */,
+                               1DE0D095211CC21300439B5F /* WKShareSheet.h */,
+                               1DBBB061211CC3CB00502ECC /* WKShareSheet.mm */,
                                F4D5F519206087A00038BBA8 /* WKTextInputListViewController.h */,
                                F4D5F51A206087A10038BBA8 /* WKTextInputListViewController.mm */,
                                2EB6FBFF203021960017E619 /* WKTimePickerViewController.h */,
                                8313F7EC1F7DAE0800B944EB /* SharedStringHashStore.h in Headers */,
                                8313F7EE1F7DAE0800B944EB /* SharedStringHashTable.h in Headers */,
                                83F9644E1FA0F76E00C47750 /* SharedStringHashTableReadOnly.h in Headers */,
+                               1D67B339212E1F6100FAA786 /* ShareSheetCallbackID.h in Headers */,
                                995226D6207D184600F78420 /* SimulatedInputDispatcher.h in Headers */,
                                2DAF06D618BD1A470081CEB1 /* SmartMagnificationController.h in Headers */,
                                2DE6943E18BD2A68005C15E5 /* SmartMagnificationControllerMessages.h in Headers */,
                                BC407604124FF0270068F20A /* WKSerializedScriptValue.h in Headers */,
                                1ADE46B31954EC61000F7985 /* WKSessionStateRef.h in Headers */,
                                BCDDB32B124EC2AB0048D13C /* WKSharedAPICast.h in Headers */,
+                               1DB01943211CF002009FB3E8 /* WKShareSheet.h in Headers */,
                                513E462D1AD837560016234A /* WKSharingServicePickerDelegate.h in Headers */,
                                93F549B41E3174B7000E7239 /* WKSnapshotConfiguration.h in Headers */,
                                BC407606124FF0270068F20A /* WKString.h in Headers */,
                                51CD1C5D1B3493AF00142CA5 /* WKSecurityOriginRef.cpp in Sources */,
                                BC407603124FF0270068F20A /* WKSerializedScriptValue.cpp in Sources */,
                                1ADE46B21954EC61000F7985 /* WKSessionStateRef.cpp in Sources */,
+                               1DB01944211CF005009FB3E8 /* WKShareSheet.mm in Sources */,
+                               513E462E1AD837560016234A /* WKSharingServicePickerDelegate.mm in Sources */,
                                93F549B61E3174DA000E7239 /* WKSnapshotConfiguration.mm in Sources */,
                                BC407605124FF0270068F20A /* WKString.cpp in Sources */,
                                BC407619124FF0370068F20A /* WKStringCF.mm in Sources */,
index e7929de..08d023b 100644 (file)
@@ -810,6 +810,11 @@ void WebChromeClient::runOpenPanel(Frame& frame, FileChooser& fileChooser)
     ASSERT(webFrame);
     m_page.send(Messages::WebPageProxy::RunOpenPanel(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), fileChooser.settings()));
 }
+    
+void WebChromeClient::showShareSheet(ShareDataWithParsedURL& shareData, CompletionHandler<void(bool)>&& callback)
+{
+    m_page.showShareSheet(shareData, WTFMove(callback));
+}
 
 void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader)
 {
index e5d8e43..5e00cd4 100644 (file)
@@ -187,6 +187,7 @@ private:
 #endif
 
     void runOpenPanel(WebCore::Frame&, WebCore::FileChooser&) final;
+    void showShareSheet(WebCore::ShareDataWithParsedURL&, WTF::CompletionHandler<void(bool)>&&) final;
     void loadIconForFiles(const Vector<String>&, WebCore::FileIconLoader&) final;
 
 #if !PLATFORM(IOS)
index 76d2759..b745aec 100644 (file)
@@ -61,6 +61,7 @@
 #include "SessionState.h"
 #include "SessionStateConversion.h"
 #include "SessionTracker.h"
+#include "ShareSheetCallbackID.h"
 #include "ShareableBitmap.h"
 #include "UserMediaPermissionRequestManager.h"
 #include "ViewGestureGeometryCollector.h"
@@ -6063,6 +6064,29 @@ void WebPage::storageAccessResponse(bool wasGranted, uint64_t contextId)
     callback(wasGranted);
 }
 #endif
+    
+static ShareSheetCallbackID nextShareSheetCallbackID()
+{
+    static ShareSheetCallbackID nextCallbackID = 0;
+    return ++nextCallbackID;
+}
+    
+void WebPage::showShareSheet(ShareDataWithParsedURL& shareData, WTF::CompletionHandler<void(bool)>&& callback)
+{
+    ShareSheetCallbackID callbackID = nextShareSheetCallbackID();
+    auto addResult = m_shareSheetResponseCallbackMap.add(callbackID, WTFMove(callback));
+    ASSERT(addResult.isNewEntry);
+    if (addResult.iterator->value)
+        send(Messages::WebPageProxy::ShowShareSheet(WTFMove(shareData), callbackID));
+    else
+        callback(false);
+}
+
+void WebPage::didCompleteShareSheet(bool wasGranted, ShareSheetCallbackID callbackID)
+{
+    auto callback = m_shareSheetResponseCallbackMap.take(callbackID);
+    callback(wasGranted);
+}
 
 #if ENABLE(ATTACHMENT_ELEMENT)
 
index 62fe50c..78fbf56 100644 (file)
@@ -44,6 +44,7 @@
 #include "OptionalCallbackID.h"
 #include "Plugin.h"
 #include "SandboxExtension.h"
+#include "ShareSheetCallbackID.h"
 #include "SharedMemory.h"
 #include "UserData.h"
 #include "WebBackForwardListProxy.h"
@@ -61,6 +62,7 @@
 #include <WebCore/PageOverlay.h>
 #include <WebCore/PluginData.h>
 #include <WebCore/SecurityPolicyViolationEvent.h>
+#include <WebCore/ShareData.h>
 #include <WebCore/UserActivity.h>
 #include <WebCore/UserContentTypes.h>
 #include <WebCore/UserInterfaceLayoutDirection.h>
@@ -1071,6 +1073,9 @@ public:
     void storageAccessResponse(bool wasGranted, uint64_t contextId);
 #endif
 
+    void showShareSheet(WebCore::ShareDataWithParsedURL&, WTF::CompletionHandler<void(bool)>&& callback);
+    void didCompleteShareSheet(bool wasCompleted, ShareSheetCallbackID contextId);
+    
 #if ENABLE(ATTACHMENT_ELEMENT)
     void insertAttachment(const String& identifier, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CallbackID);
     void updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, const String& fileName, CallbackID);
@@ -1724,7 +1729,8 @@ private:
     HashMap<String, RefPtr<WebURLSchemeHandlerProxy>> m_schemeToURLSchemeHandlerProxyMap;
     HashMap<uint64_t, WebURLSchemeHandlerProxy*> m_identifierToURLSchemeHandlerProxyMap;
 
-    HashMap<uint64_t, WTF::Function<void (bool granted)>> m_storageAccessResponseCallbackMap;
+    HashMap<uint64_t, WTF::Function<void(bool granted)>> m_storageAccessResponseCallbackMap;
+    HashMap<ShareSheetCallbackID, WTF::Function<void(bool completed)>> m_shareSheetResponseCallbackMap;
 
 #if ENABLE(APPLICATION_MANIFEST)
     HashMap<uint64_t, uint64_t> m_applicationManifestFetchCallbackMap;
index 7e96a7a..8c41145 100644 (file)
@@ -290,6 +290,7 @@ messages -> WebPage LegacyReceiver {
 #endif
     DidChooseFilesForOpenPanel(Vector<String> fileURLs)
     DidCancelForOpenPanel()
+    DidCompleteShareSheet(bool wasGranted, uint64_t callbackID)
 #if ENABLE(SANDBOX_EXTENSIONS)
     ExtendSandboxForFilesFromOpenPanel(WebKit::SandboxExtension::HandleArray sandboxExtensions)
 #endif
index 565a20d..cbce570 100644 (file)
@@ -1,3 +1,16 @@
+2018-08-29  Olivia Barnett  <obarnett@apple.com>
+
+        Implement the Web Share API
+        https://bugs.webkit.org/show_bug.cgi?id=171100
+        <rdar://problem/31751734>
+
+        Reviewed by Tim Horton.
+
+        * WebCoreSupport/WebChromeClientIOS.h:
+        * WebCoreSupport/WebChromeClientIOS.mm:
+        (WebChromeClientIOS::showShareSheet):
+        Empty declaration of showShareSheet.
+
 2018-08-24  Ryosuke Niwa  <rniwa@webkit.org>
 
         Pass in IsComposed flag to Event constructors
index bc1583c..e2f5ed2 100644 (file)
@@ -47,6 +47,7 @@ private:
     bool runJavaScriptPrompt(WebCore::Frame&, const WTF::String& message, const WTF::String& defaultValue, WTF::String& result) final;
 
     void runOpenPanel(WebCore::Frame&, WebCore::FileChooser&) final;
+    void showShareSheet(WebCore::ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&) final;
 
 #if ENABLE(TOUCH_EVENTS)
     void didPreventDefaultForEvent() final;
index c701870..7d4f209 100644 (file)
@@ -157,6 +157,10 @@ void WebChromeClientIOS::runOpenPanel(Frame&, FileChooser& chooser)
     [listener release];
 }
 
+void WebChromeClientIOS::showShareSheet(ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&)
+{
+}
+
 #if ENABLE(IOS_TOUCH_EVENTS)
 
 void WebChromeClientIOS::didPreventDefaultForEvent()
index 276c537..99b64c0 100644 (file)
@@ -1,3 +1,16 @@
+2018-08-29  Olivia Barnett  <obarnett@apple.com>
+
+        Implement the Web Share API
+        https://bugs.webkit.org/show_bug.cgi?id=171100
+        <rdar://problem/31751734>
+
+        Reviewed by Tim Horton.
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::showShareSheet):
+        Empty declaration of showShareSheet.
+
 2018-08-29  Youenn Fablet  <youenn@apple.com>
 
         Remove WebRTC legacy API implementation
index 4355a86..1a70bce 100644 (file)
@@ -126,6 +126,8 @@ private:
 #endif
 
     void runOpenPanel(WebCore::Frame&, WebCore::FileChooser&) override;
+    void showShareSheet(WebCore::ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&) override;
+
     void loadIconForFiles(const Vector<String>&, WebCore::FileIconLoader&) final;
     RefPtr<WebCore::Icon> createIconForFiles(const Vector<String>& filenames) override;
 
index 2884dfd..58784b9 100644 (file)
@@ -776,6 +776,10 @@ void WebChromeClient::runOpenPanel(Frame&, FileChooser& chooser)
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
+void WebChromeClient::showShareSheet(ShareDataWithParsedURL&, CompletionHandler<void(bool)>&&)
+{
+}
+
 void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& iconLoader)
 {
     iconLoader.iconLoaded(createIconForFiles(filenames));
index 76425b9..bc9b210 100644 (file)
@@ -159,6 +159,10 @@ void UIScriptController::setTimePickerValue(long, long)
 {
 }
 
+void UIScriptController::invokeShareSheetWithResolution(bool)
+{
+}
+
 void UIScriptController::selectFormAccessoryPickerRow(long rowIndex)
 {
 }
index abf8470..ab6a924 100644 (file)
@@ -193,6 +193,9 @@ interface UIScriptController {
 
     void setTimePickerValue(long hour, long minute);
 
+    // Share sheet
+    void invokeShareSheetWithResolution(boolean resolved);
+
     // <datalist>
     readonly attribute boolean isShowingDataListSuggestions;
 
index 492c948..b7c16f5 100644 (file)
@@ -294,6 +294,10 @@ void UIScriptController::setTimePickerValue(long, long)
 {
 }
 
+void UIScriptController::invokeShareSheetWithResolution(bool)
+{
+}
+
 void UIScriptController::selectFormAccessoryPickerRow(long)
 {
 }
index 7fd74da..98e6557 100644 (file)
@@ -101,6 +101,8 @@ public:
     JSRetainPtr<JSStringRef> formInputLabel() const;
     void setTimePickerValue(long hour, long minute);
 
+    void invokeShareSheetWithResolution(bool resolved);
+
     bool isShowingDataListSuggestions() const;
 
     JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const;
index 6597040..593afc0 100644 (file)
@@ -409,6 +409,12 @@ void UIScriptController::setTimePickerValue(long hour, long minute)
     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
     [webView setTimePickerValueToHour:hour minute:minute];
 }
+
+void UIScriptController::invokeShareSheetWithResolution(bool resolved)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    [webView _invokeShareSheetWithResolution:resolved];
+}
     
 JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
 {