[Web App Manifest] Add SPI for fetching the manifest
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Dec 2017 22:26:32 +0000 (22:26 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Dec 2017 22:26:32 +0000 (22:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180294
rdar://problem/34747968

Patch by David Quesada <david_quesada@apple.com> on 2017-12-06
Reviewed by Geoffrey Garen.

Source/WebCore:

Test: applicationmanifest/developer-warnings.html

* Modules/applicationmanifest/ApplicationManifest.h:
(WebCore::ApplicationManifest::encode const):
(WebCore::ApplicationManifest::decode):
* Modules/applicationmanifest/ApplicationManifestParser.cpp:
(WebCore::ApplicationManifestParser::logManifestPropertyNotAString):
(WebCore::ApplicationManifestParser::logManifestPropertyInvalidURL):
    Drive-by wording changes. Since the warning is prefixed with "parsing
    application manifest:", remove a redundant use of "application manifest".

Source/WebKit:

Add a new method -[WKWebView _getApplicationManifestWithCompletionHandler:] to request
the manifest associated with the current page.

* Shared/API/APIObject.h:
* Shared/Cocoa/APIObject.mm:
(API::Object::newObject):
* UIProcess/API/APIApplicationManifest.h: Copied from Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h.
    Add a new API object type for application manifests.
* UIProcess/API/C/WKPage.cpp:
(WKPageGetApplicationManifest_b):
    Add a C version of this SPI for WebKitTestRunner.
* UIProcess/API/C/WKPagePrivate.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _getApplicationManifestWithCompletionHandler:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/API/Cocoa/_WKApplicationManifest.h: Copied from Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h.
* UIProcess/API/Cocoa/_WKApplicationManifest.mm: Added.
(-[_WKApplicationManifest initWithCoder:]):
(-[_WKApplicationManifest encodeWithCoder:]):
(+[_WKApplicationManifest applicationManifestFromJSON:manifestURL:documentURL:]):
(-[_WKApplicationManifest _apiObject]):
(nullableNSString):
(-[_WKApplicationManifest name]):
(-[_WKApplicationManifest shortName]):
(-[_WKApplicationManifest applicationDescription]):
(-[_WKApplicationManifest scope]):
(-[_WKApplicationManifest startURL]):
* UIProcess/API/Cocoa/_WKApplicationManifestInternal.h: Copied from Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h.
(API::wrapper):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::applicationManifestCallback):
(WebKit::WebPageProxy::getApplicationManifest):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::finishedLoadingApplicationManifest):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::getApplicationManifest):
(WebKit::WebPage::didFinishLoadingApplicationManifest):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm: Added.
    Added two API tests for _WKApplicationManifest:
    - Testing _WKApplicationManifest's conformance to NSCoding.
    - Testing -[WKWebView _getApplicationManifestWithCompletionHandler:], verifying the
      values of the resulting _WKApplicationManifest.
(TestWebKitAPI::TEST):

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
    Added a new testRunner method getApplicationManifestThen(), used by the LayoutTests
    to request the document load its associated manifest. The layout tests formerly called
    an unimplemented function getManifestThen(), but I added 'Application' to somewhat
    differentiate this from the app cache manifest.

* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessageToPage):
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::getApplicationManifestThen):
(WTR::TestRunner::didGetApplicationManifest):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

LayoutTests:

* TestExpectations:
    Skip the app manifest-related layout tests for now while the feature is still disabled.
    Also moved the expectations disabling the manifest-src layout tests (which now pass
    when the feature is enabled) to the same location in the file.
* applicationmanifest/developer-warnings-expected.txt: Added.
* applicationmanifest/developer-warnings.html: Added.
* applicationmanifest/multiple-links-expected.txt: Added.
* applicationmanifest/multiple-links.html: Added.
    Add a layout test to verify only the first manifest link is loaded when there
    are multiple on the page.
* applicationmanifest/resources/developer-warnings.manifest: Added.
    Add a layout test to verify that warnings generated while parsing the manifest are
    logged to the console.
* http/tests/security/contentSecurityPolicy/manifest-src-allowed.html:
    Replaced calls to getManifestThen() with getApplicationManifestThen().
* http/tests/security/contentSecurityPolicy/manifest-src-blocked-expected.txt:
    Updated the expected console message to reflect the current wording for CSP violations.
* http/tests/security/contentSecurityPolicy/manifest-src-blocked.html:
    Replaced calls to getManifestThen() with getApplicationManifestThen().
* http/tests/security/contentSecurityPolicy/manifest.test/manifest.json:
    Removed a trailing newline that was causing JSON parsing to fail.

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

42 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/applicationmanifest/developer-warnings-expected.txt [new file with mode: 0644]
LayoutTests/applicationmanifest/developer-warnings.html [new file with mode: 0644]
LayoutTests/applicationmanifest/multiple-links-expected.txt [new file with mode: 0644]
LayoutTests/applicationmanifest/multiple-links.html [new file with mode: 0644]
LayoutTests/applicationmanifest/resources/developer-warnings.manifest [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-allowed.html
LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked.html
LayoutTests/http/tests/security/contentSecurityPolicy/manifest.test/manifest.json
Source/WebCore/ChangeLog
Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h
Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp
Source/WebKit/ChangeLog
Source/WebKit/Shared/API/APIObject.h
Source/WebKit/Shared/Cocoa/APIObject.mm
Source/WebKit/UIProcess/API/APIApplicationManifest.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/C/WKPage.cpp
Source/WebKit/UIProcess/API/C/WKPagePrivate.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifestInternal.h [new file with mode: 0644]
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm [new file with mode: 0644]
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestInvocation.cpp

index 5138c1d..68e47f7 100644 (file)
@@ -1,3 +1,33 @@
+2017-12-06  David Quesada  <david_quesada@apple.com>
+
+        [Web App Manifest] Add SPI for fetching the manifest
+        https://bugs.webkit.org/show_bug.cgi?id=180294
+        rdar://problem/34747968
+
+        Reviewed by Geoffrey Garen.
+
+        * TestExpectations:
+            Skip the app manifest-related layout tests for now while the feature is still disabled.
+            Also moved the expectations disabling the manifest-src layout tests (which now pass
+            when the feature is enabled) to the same location in the file.
+        * applicationmanifest/developer-warnings-expected.txt: Added.
+        * applicationmanifest/developer-warnings.html: Added.
+        * applicationmanifest/multiple-links-expected.txt: Added.
+        * applicationmanifest/multiple-links.html: Added.
+            Add a layout test to verify only the first manifest link is loaded when there
+            are multiple on the page.
+        * applicationmanifest/resources/developer-warnings.manifest: Added.
+            Add a layout test to verify that warnings generated while parsing the manifest are
+            logged to the console.
+        * http/tests/security/contentSecurityPolicy/manifest-src-allowed.html:
+            Replaced calls to getManifestThen() with getApplicationManifestThen().
+        * http/tests/security/contentSecurityPolicy/manifest-src-blocked-expected.txt:
+            Updated the expected console message to reflect the current wording for CSP violations.
+        * http/tests/security/contentSecurityPolicy/manifest-src-blocked.html:
+            Replaced calls to getManifestThen() with getApplicationManifestThen().
+        * http/tests/security/contentSecurityPolicy/manifest.test/manifest.json:
+            Removed a trailing newline that was causing JSON parsing to fail.
+
 2017-12-06  Youenn Fablet  <youenn@apple.com>
 
         Import WPT workers test suite
index 186fd67..993ab39 100644 (file)
@@ -1110,8 +1110,6 @@ webkit.org/b/111869 http/tests/security/contentSecurityPolicy/eval-blocked-and-s
 webkit.org/b/153148 http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.php
 webkit.org/b/153150 http/tests/security/contentSecurityPolicy/1.1/child-src/frame-fires-load-event-when-blocked.html
 webkit.org/b/153150 http/tests/security/contentSecurityPolicy/1.1/child-src/frame-fires-load-event-when-redirect-blocked.html
-webkit.org/b/153152 http/tests/security/contentSecurityPolicy/manifest-src-allowed.html # Needs testRunner.getManifestThen()
-webkit.org/b/153152 http/tests/security/contentSecurityPolicy/manifest-src-blocked.html # Needs testRunner.getManifestThen()
 webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-error-event.html
 webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html
 webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html
@@ -1650,3 +1648,9 @@ webkit.org/b/179287 http/wpt/web-animations/interfaces/AnimationTimeline/documen
 webkit.org/b/179287 http/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html [ Pass Failure ]
 
 webkit.org/b/177440 imported/w3c/web-platform-tests/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html [ Pass Failure ]
+
+# Application Manifest tests
+webkit.org/b/153152 http/tests/security/contentSecurityPolicy/manifest-src-allowed.html [ Skip ]
+webkit.org/b/153152 http/tests/security/contentSecurityPolicy/manifest-src-blocked.html [ Skip ]
+webkit.org/b/158205 applicationmanifest/ [ Skip ]
+
diff --git a/LayoutTests/applicationmanifest/developer-warnings-expected.txt b/LayoutTests/applicationmanifest/developer-warnings-expected.txt
new file mode 100644 (file)
index 0000000..b320f45
--- /dev/null
@@ -0,0 +1,4 @@
+CONSOLE MESSAGE: Parsing application manifest developer-warnings.manifest: The value of "start_url" is not a valid URL.
+CONSOLE MESSAGE: Parsing application manifest developer-warnings.manifest: The value of "name" is not a string.
+ALERT: Pass
+
diff --git a/LayoutTests/applicationmanifest/developer-warnings.html b/LayoutTests/applicationmanifest/developer-warnings.html
new file mode 100644 (file)
index 0000000..3e5bc77
--- /dev/null
@@ -0,0 +1,11 @@
+<link rel="manifest" href="resources/developer-warnings.manifest">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+    testRunner.getApplicationManifestThen(function() {
+        alert("Pass");
+        testRunner.notifyDone();
+    });
+}
+</script>
diff --git a/LayoutTests/applicationmanifest/multiple-links-expected.txt b/LayoutTests/applicationmanifest/multiple-links-expected.txt
new file mode 100644 (file)
index 0000000..90c7896
--- /dev/null
@@ -0,0 +1,4 @@
+multiple-links.html - didFinishLoading
+urlscheme://1 - willSendRequest <NSURLRequest URL urlscheme://1, main document URL multiple-links.html, http method GET> redirectResponse (null)
+urlscheme://1 - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1002, failing URL "urlscheme://1">
+
diff --git a/LayoutTests/applicationmanifest/multiple-links.html b/LayoutTests/applicationmanifest/multiple-links.html
new file mode 100644 (file)
index 0000000..007bb8f
--- /dev/null
@@ -0,0 +1,12 @@
+<link rel="manifest" href="urlscheme://1" media="print">
+<link rel="manifest" href="urlscheme://2">
+<script>
+if (window.testRunner) {
+    testRunner.dumpResourceLoadCallbacks();
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+    testRunner.getApplicationManifestThen(function() {
+        testRunner.notifyDone();
+    });
+}
+</script>
\ No newline at end of file
diff --git a/LayoutTests/applicationmanifest/resources/developer-warnings.manifest b/LayoutTests/applicationmanifest/resources/developer-warnings.manifest
new file mode 100644 (file)
index 0000000..6a0bb08
--- /dev/null
@@ -0,0 +1,4 @@
+{
+    "name": 0,
+    "start_url": "http:?"
+}
\ No newline at end of file
index ddbd47d..ef5e10a 100644 (file)
@@ -4,7 +4,7 @@
     if (window.testRunner) {
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
-        testRunner.getManifestThen(function() {
+        testRunner.getApplicationManifestThen(function() {
             alert("Pass");
             testRunner.notifyDone();
         });
index 706b885..2f651c6 100644 (file)
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: Refused to load manifest from 'http://127.0.0.1:8000/security/contentSecurityPolicy/manifest.test/manifest.json' because it violates the following Content Security Policy directive: "manifest-src 'none'".
-
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/manifest.test/manifest.json because it does not appear in the manifest-src directive of the Content Security Policy.
 ALERT: Pass
 
index a7df714..cd4d1f7 100644 (file)
@@ -4,7 +4,7 @@
     if (window.testRunner) {
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
-        testRunner.getManifestThen(function() {
+        testRunner.getApplicationManifestThen(function() {
             alert("Pass");
             testRunner.notifyDone();
         });
index 88ec3a4..02364ac 100644 (file)
@@ -1,3 +1,22 @@
+2017-12-06  David Quesada  <david_quesada@apple.com>
+
+        [Web App Manifest] Add SPI for fetching the manifest
+        https://bugs.webkit.org/show_bug.cgi?id=180294
+        rdar://problem/34747968
+
+        Reviewed by Geoffrey Garen.
+
+        Test: applicationmanifest/developer-warnings.html
+
+        * Modules/applicationmanifest/ApplicationManifest.h:
+        (WebCore::ApplicationManifest::encode const):
+        (WebCore::ApplicationManifest::decode):
+        * Modules/applicationmanifest/ApplicationManifestParser.cpp:
+        (WebCore::ApplicationManifestParser::logManifestPropertyNotAString):
+        (WebCore::ApplicationManifestParser::logManifestPropertyInvalidURL):
+            Drive-by wording changes. Since the warning is prefixed with "parsing
+            application manifest:", remove a redundant use of "application manifest".
+
 2017-12-06  Per Arne Vollan  <pvollan@apple.com>
 
         The WebProcess should use the NSRunLoop runloop type.
index ef96269..c70e7e6 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(APPLICATION_MANIFEST)
 
 #include "URL.h"
+#include <wtf/Optional.h>
 
 namespace WebCore {
 
@@ -37,8 +38,36 @@ struct ApplicationManifest {
     String description;
     URL scope;
     URL startURL;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<ApplicationManifest> decode(Decoder&);
 };
 
+template<class Encoder>
+void ApplicationManifest::encode(Encoder& encoder) const
+{
+    encoder << name << shortName << description << scope << startURL;
+}
+
+template<class Decoder>
+std::optional<ApplicationManifest> ApplicationManifest::decode(Decoder& decoder)
+{
+    ApplicationManifest result;
+
+    if (!decoder.decode(result.name))
+        return std::nullopt;
+    if (!decoder.decode(result.shortName))
+        return std::nullopt;
+    if (!decoder.decode(result.description))
+        return std::nullopt;
+    if (!decoder.decode(result.scope))
+        return std::nullopt;
+    if (!decoder.decode(result.startURL))
+        return std::nullopt;
+
+    return result;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(APPLICATION_MANIFEST)
index 467e568..0970a52 100644 (file)
@@ -79,12 +79,12 @@ ApplicationManifest ApplicationManifestParser::parseManifest(const String& text,
 
 void ApplicationManifestParser::logManifestPropertyNotAString(const String& propertyName)
 {
-    logDeveloperWarning("The \"" + propertyName + "\" application manifest property is not a string.");
+    logDeveloperWarning("The value of \"" + propertyName + "\" is not a string.");
 }
 
 void ApplicationManifestParser::logManifestPropertyInvalidURL(const String& propertyName)
 {
-    logDeveloperWarning("The \"" + propertyName + "\" application manifest property is not a valid URL.");
+    logDeveloperWarning("The value of \"" + propertyName + "\" is not a valid URL.");
 }
 
 void ApplicationManifestParser::logDeveloperWarning(const String& message)
index e5dea24..0455d57 100644 (file)
@@ -1,3 +1,55 @@
+2017-12-06  David Quesada  <david_quesada@apple.com>
+
+        [Web App Manifest] Add SPI for fetching the manifest
+        https://bugs.webkit.org/show_bug.cgi?id=180294
+        rdar://problem/34747968
+
+        Reviewed by Geoffrey Garen.
+
+        Add a new method -[WKWebView _getApplicationManifestWithCompletionHandler:] to request
+        the manifest associated with the current page.
+
+        * Shared/API/APIObject.h:
+        * Shared/Cocoa/APIObject.mm:
+        (API::Object::newObject):
+        * UIProcess/API/APIApplicationManifest.h: Copied from Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h.
+            Add a new API object type for application manifests.
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageGetApplicationManifest_b):
+            Add a C version of this SPI for WebKitTestRunner.
+        * UIProcess/API/C/WKPagePrivate.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _getApplicationManifestWithCompletionHandler:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/API/Cocoa/_WKApplicationManifest.h: Copied from Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h.
+        * UIProcess/API/Cocoa/_WKApplicationManifest.mm: Added.
+        (-[_WKApplicationManifest initWithCoder:]):
+        (-[_WKApplicationManifest encodeWithCoder:]):
+        (+[_WKApplicationManifest applicationManifestFromJSON:manifestURL:documentURL:]):
+        (-[_WKApplicationManifest _apiObject]):
+        (nullableNSString):
+        (-[_WKApplicationManifest name]):
+        (-[_WKApplicationManifest shortName]):
+        (-[_WKApplicationManifest applicationDescription]):
+        (-[_WKApplicationManifest scope]):
+        (-[_WKApplicationManifest startURL]):
+        * UIProcess/API/Cocoa/_WKApplicationManifestInternal.h: Copied from Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h.
+        (API::wrapper):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::applicationManifestCallback):
+        (WebKit::WebPageProxy::getApplicationManifest):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::finishedLoadingApplicationManifest):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::getApplicationManifest):
+        (WebKit::WebPage::didFinishLoadingApplicationManifest):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2017-12-06  Per Arne Vollan  <pvollan@apple.com>
 
         The WebProcess should use the NSRunLoop runloop type.
index f07414c..75572a6 100644 (file)
@@ -97,6 +97,9 @@ public:
         
         // UIProcess types
         ApplicationCacheManager,
+#if ENABLE(APPLICATION_MANIFEST)
+        ApplicationManifest,
+#endif
         Attachment,
         AutomationSession,
         BackForwardList,
index dfba9fd..c75b231 100644 (file)
 #import "_WKUserStyleSheetInternal.h"
 #import "_WKVisitedLinkStoreInternal.h"
 
+#if ENABLE(APPLICATION_MANIFEST)
+#import "_WKApplicationManifestInternal.h"
+#endif
+
 static const size_t minimumObjectAlignment = 8;
 static_assert(minimumObjectAlignment >= alignof(void*), "Objects should always be at least pointer-aligned.");
 static const size_t maximumExtraSpaceForAlignment = minimumObjectAlignment - alignof(void*);
@@ -119,6 +123,12 @@ void* Object::newObject(size_t size, Type type)
     // API::Object, so they are allocated using +alloc.
 
     switch (type) {
+#if ENABLE(APPLICATION_MANIFEST)
+    case Type::ApplicationManifest:
+        wrapper = [_WKApplicationManifest alloc];
+        break;
+#endif
+
     case Type::Array:
         wrapper = [WKNSArray alloc];
         break;
diff --git a/Source/WebKit/UIProcess/API/APIApplicationManifest.h b/Source/WebKit/UIProcess/API/APIApplicationManifest.h
new file mode 100644 (file)
index 0000000..ed33148
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "APIObject.h"
+#include <WebCore/ApplicationManifest.h>
+
+namespace API {
+
+#if ENABLE(APPLICATION_MANIFEST)
+class ApplicationManifest final : public ObjectImpl<Object::Type::ApplicationManifest> {
+public:
+    static Ref<ApplicationManifest> create(const WebCore::ApplicationManifest& applicationManifest)
+    {
+        return adoptRef(*new ApplicationManifest(applicationManifest));
+    }
+
+    explicit ApplicationManifest(const WebCore::ApplicationManifest& applicationManifest)
+        : m_applicationManifest(applicationManifest)
+    {
+    }
+
+    const WebCore::ApplicationManifest& applicationManifest() const { return m_applicationManifest; }
+
+private:
+    WebCore::ApplicationManifest m_applicationManifest;
+};
+#endif
+
+} // namespace API
+
index f2244d7..32e4f4a 100644 (file)
@@ -2760,3 +2760,17 @@ ProcessID WKPageGetProcessIdentifier(WKPageRef page)
 {
     return toImpl(page)->processIdentifier();
 }
+
+#ifdef __BLOCKS__
+void WKPageGetApplicationManifest_b(WKPageRef page, WKPageGetApplicationManifestBlock block)
+{
+#if ENABLE(APPLICATION_MANIFEST)
+    toImpl(page)->getApplicationManifest([block](const std::optional<WebCore::ApplicationManifest> &manifest, CallbackBase::Error) {
+        block();
+    });
+#else // ENABLE(APPLICATION_MANIFEST)
+    UNUSED_PARAM(page);
+    block();
+#endif // not ENABLE(APPLICATION_MANIFEST)
+}
+#endif
index 0df8364..bb26de8 100644 (file)
@@ -178,6 +178,11 @@ WK_EXPORT void WKPageSetIgnoresViewportScaleLimits(WKPageRef page, bool ignoresV
 
 WK_EXPORT WKProcessID WKPageGetProcessIdentifier(WKPageRef page);
 
+#ifdef __BLOCKS__
+typedef void (^WKPageGetApplicationManifestBlock)(void);
+WK_EXPORT void WKPageGetApplicationManifest_b(WKPageRef page, WKPageGetApplicationManifestBlock block);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
index 4d2403c..44db8c9 100644 (file)
 #import <wtf/spi/darwin/dyldSPI.h>
 #import <wtf/text/TextStream.h>
 
+#if ENABLE(APPLICATION_MANIFEST)
+#import "_WKApplicationManifestInternal.h"
+#endif
+
 #if ENABLE(DATA_DETECTION)
 #import "WKDataDetectorTypesInternal.h"
 #endif
@@ -4344,6 +4348,25 @@ static inline WebCore::LayoutMilestones layoutMilestones(_WKRenderingProgressEve
     });
 }
 
+- (void)_getApplicationManifestWithCompletionHandler:(void (^)(_WKApplicationManifest *))completionHandler
+{
+#if ENABLE(APPLICATION_MANIFEST)
+    _page->getApplicationManifest([completionHandler = makeBlockPtr(completionHandler)](const std::optional<WebCore::ApplicationManifest>& manifest, WebKit::CallbackBase::Error error) {
+        UNUSED(error);
+        if (completionHandler) {
+            if (manifest) {
+                auto apiManifest = API::ApplicationManifest::create(*manifest);
+                completionHandler(wrapper(apiManifest));
+            } else
+                completionHandler(nil);
+        }
+    });
+#else
+    if (completionHandler)
+        completionHandler(nil);
+#endif
+}
+
 - (_WKPaginationMode)_paginationMode
 {
     switch (_page->paginationMode()) {
index 966fb9b..57d822f 100644 (file)
@@ -96,6 +96,7 @@ typedef NS_OPTIONS(NSInteger, _WKRectEdge) {
 #endif
 
 @class WKBrowsingContextHandle;
+@class _WKApplicationManifest;
 @class _WKFrameHandle;
 @class _WKHitTestResult;
 @class _WKIconLoadingDelegate;
@@ -307,6 +308,8 @@ typedef NS_OPTIONS(NSInteger, _WKRectEdge) {
 - (void)_getWebArchiveDataWithCompletionHandler:(void (^)(NSData *, NSError *))completionHandler;
 - (void)_getContentsAsStringWithCompletionHandler:(void (^)(NSString *, NSError *))completionHandler WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 
+- (void)_getApplicationManifestWithCompletionHandler:(void (^)(_WKApplicationManifest *))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @property (nonatomic, setter=_setPaginationMode:) _WKPaginationMode _paginationMode;
 // Whether the column-break-{before,after} properties are respected instead of the
 // page-break-{before,after} properties.
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h b/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h
new file mode 100644 (file)
index 0000000..61c50f2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#import <WebKit/WKFoundation.h>
+
+#if WK_API_ENABLED
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+WK_CLASS_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKApplicationManifest : NSObject <NSCoding>
+
+@property (nonatomic, readonly, nullable, copy) NSString *name;
+@property (nonatomic, readonly, nullable, copy) NSString *shortName;
+@property (nonatomic, readonly, nullable, copy) NSString *applicationDescription;
+@property (nonatomic, readonly, nullable, copy) NSURL *scope;
+@property (nonatomic, readonly, copy) NSURL *startURL;
+
++ (_WKApplicationManifest *)applicationManifestFromJSON:(NSString *)json manifestURL:(NSURL *)manifestURL documentURL:(nullable NSURL *)documentURL;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif // WK_API_ENABLED
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm
new file mode 100644 (file)
index 0000000..4f5e9a1
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2017 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 "_WKApplicationManifestInternal.h"
+
+#if WK_API_ENABLED
+
+#import <WebCore/ApplicationManifest.h>
+#import <WebCore/ApplicationManifestParser.h>
+
+@implementation _WKApplicationManifest
+
+#if ENABLE(APPLICATION_MANIFEST)
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder
+{
+    NSString *name = [aDecoder decodeObjectForKey:@"name"];
+    NSString *shortName = [aDecoder decodeObjectForKey:@"short_name"];
+    NSString *description = [aDecoder decodeObjectForKey:@"description"];
+    NSURL *scopeURL = [aDecoder decodeObjectForKey:@"scope"];
+    NSURL *startURL = [aDecoder decodeObjectForKey:@"start_url"];
+
+    WebCore::ApplicationManifest coreApplicationManifest {
+        WTF::String(name),
+        WTF::String(shortName),
+        WTF::String(description),
+        WebCore::URL(scopeURL),
+        WebCore::URL(startURL)
+    };
+
+    API::Object::constructInWrapper<API::ApplicationManifest>(self, WTFMove(coreApplicationManifest));
+
+    return self;
+}
+
+- (void)dealloc
+{
+    _applicationManifest->~ApplicationManifest();
+
+    [super dealloc];
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+    [aCoder encodeObject:self.name forKey:@"name"];
+    [aCoder encodeObject:self.shortName forKey:@"short_name"];
+    [aCoder encodeObject:self.applicationDescription forKey:@"description"];
+    [aCoder encodeObject:self.scope forKey:@"scope"];
+    [aCoder encodeObject:self.startURL forKey:@"start_url"];
+}
+
++ (_WKApplicationManifest *)applicationManifestFromJSON:(NSString *)json manifestURL:(NSURL *)manifestURL documentURL:(NSURL *)documentURL
+{
+    auto manifest = WebCore::ApplicationManifestParser::parse(WTF::String(json), WebCore::URL(manifestURL), WebCore::URL(documentURL));
+    return [API::wrapper(API::ApplicationManifest::create(manifest).leakRef()) autorelease];
+}
+
+- (API::Object&)_apiObject
+{
+    return *_applicationManifest;
+}
+
+static NSString *nullableNSString(const WTF::String& string)
+{
+    return string.isNull() ? nil : (NSString *)string;
+}
+
+- (NSString *)name
+{
+    return nullableNSString(_applicationManifest->applicationManifest().name);
+}
+
+- (NSString *)shortName
+{
+    return nullableNSString(_applicationManifest->applicationManifest().shortName);
+}
+
+- (NSString *)applicationDescription
+{
+    return nullableNSString(_applicationManifest->applicationManifest().description);
+}
+
+- (NSURL *)scope
+{
+    return _applicationManifest->applicationManifest().scope;
+}
+
+- (NSURL *)startURL
+{
+    return _applicationManifest->applicationManifest().startURL;
+}
+
+#else // ENABLE(APPLICATION_MANIFEST)
+
++ (_WKApplicationManifest *)applicationManifestFromJSON:(NSString *)json manifestURL:(NSURL *)manifestURL documentURL:(NSURL *)documentURL
+{
+    UNUSED_PARAM(json);
+    UNUSED_PARAM(manifestURL);
+    UNUSED_PARAM(documentURL);
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder
+{
+    UNUSED_PARAM(aDecoder);
+    [self release];
+    return nil;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+    UNUSED_PARAM(aCoder);
+}
+
+- (NSString *)name
+{
+    return nil;
+}
+
+- (NSString *)shortName
+{
+    return nil;
+}
+
+- (NSString *)applicationDescription
+{
+    return nil;
+}
+
+- (NSURL *)scope
+{
+    return nil;
+}
+
+- (NSURL *)startURL
+{
+    return nil;
+}
+
+#endif // ENABLE(APPLICATION_MANIFEST)
+
+@end
+
+#endif // WK_API_ENABLED
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifestInternal.h b/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifestInternal.h
new file mode 100644 (file)
index 0000000..2b87886
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#import <WebKit/WKFoundation.h>
+
+#if WK_API_ENABLED
+
+#import "APIApplicationManifest.h"
+#import "_WKApplicationManifest.h"
+#import <WebCore/ApplicationManifest.h>
+
+namespace WebCore {
+struct ApplicationManifest;
+}
+
+#if ENABLE(APPLICATION_MANIFEST)
+namespace API {
+
+inline _WKApplicationManifest *wrapper(API::ApplicationManifest& applicationManifest)
+{
+    ASSERT([applicationManifest.wrapper() isKindOfClass:[_WKApplicationManifest class]]);
+    return (_WKApplicationManifest *)applicationManifest.wrapper();
+}
+
+}
+
+@interface _WKApplicationManifest () <WKObject> {
+@package
+    API::ObjectStorage<API::ApplicationManifest> _applicationManifest;
+}
+
+@end
+
+#endif // ENABLE(APPLICATION_MANIFEST)
+
+#endif // WK_API_ENABLED
index cd20355..49975ce 100644 (file)
@@ -5313,6 +5313,17 @@ void WebPageProxy::editingRangeCallback(const EditingRange& range, CallbackID ca
     callback->performCallbackWithReturnValue(range);
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+void WebPageProxy::applicationManifestCallback(const std::optional<WebCore::ApplicationManifest>& manifestOrNull, CallbackID callbackID)
+{
+    auto callback = m_callbacks.take<ApplicationManifestCallback>(callbackID);
+    if (!callback)
+        return;
+
+    callback->performCallbackWithReturnValue(manifestOrNull);
+}
+#endif
+
 #if PLATFORM(COCOA)
 void WebPageProxy::machSendRightCallback(const MachSendRight& sendRight, CallbackID callbackID)
 {
@@ -7231,4 +7242,18 @@ void WebPageProxy::didRemoveAttachment(const String& identifier)
 
 #endif // ENABLE(ATTACHMENT_ELEMENT)
 
+#if ENABLE(APPLICATION_MANIFEST)
+void WebPageProxy::getApplicationManifest(Function<void(const std::optional<WebCore::ApplicationManifest>&, CallbackBase::Error)>&& callbackFunction)
+{
+    if (!isValid()) {
+        callbackFunction(std::nullopt, CallbackBase::Error::Unknown);
+        return;
+    }
+
+    auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+    m_loadDependentStringCallbackIDs.add(callbackID);
+    m_process->send(Messages::WebPage::GetApplicationManifest(callbackID), m_pageID);
+}
+#endif
+
 } // namespace WebKit
index 16b5aeb..0d5c8e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -158,6 +158,7 @@ class SharedBuffer;
 class TextIndicator;
 class ValidationBubble;
 
+struct ApplicationManifest;
 struct DictionaryPopupInfo;
 struct ExceptionDetails;
 struct FileChooserSettings;
@@ -266,6 +267,10 @@ struct QueuedTouchEvents {
 typedef GenericCallback<const String&, bool, int32_t> ValidateCommandCallback;
 typedef GenericCallback<const WebCore::IntRect&, const EditingRange&> RectForCharacterRangeCallback;
 
+#if ENABLE(APPLICATION_MANIFEST)
+typedef GenericCallback<const std::optional<WebCore::ApplicationManifest>&> ApplicationManifestCallback;
+#endif
+
 #if PLATFORM(MAC)
 typedef GenericCallback<const AttributedString&, const EditingRange&> AttributedStringForCharacterRangeCallback;
 typedef GenericCallback<const String&, double, bool> FontAtSelectionCallback;
@@ -1244,6 +1249,10 @@ public:
     void setAttachmentDataAndContentType(const String& identifier, WebCore::SharedBuffer& data, std::optional<String>&& newContentType, std::optional<String>&& newFilename, Function<void(CallbackBase::Error)>&&);
 #endif
 
+#if ENABLE(APPLICATION_MANIFEST)
+    void getApplicationManifest(Function<void(const std::optional<WebCore::ApplicationManifest>&, CallbackBase::Error)>&&);
+#endif
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
     void platformInitialize();
@@ -1504,6 +1513,9 @@ private:
     void validateCommandCallback(const String&, bool, int, CallbackID);
     void unsignedCallback(uint64_t, CallbackID);
     void editingRangeCallback(const EditingRange&, CallbackID);
+#if ENABLE(APPLICATION_MANIFEST)
+    void applicationManifestCallback(const std::optional<WebCore::ApplicationManifest>&, CallbackID);
+#endif
 #if PLATFORM(COCOA)
     void machSendRightCallback(const WebCore::MachSendRight&, CallbackID);
 #endif
index 1268ce4..3c190e9 100644 (file)
@@ -167,6 +167,9 @@ messages -> WebPageProxy {
     EditingRangeCallback(struct WebKit::EditingRange range, WebKit::CallbackID callbackID)
     UnsignedCallback(uint64_t result, WebKit::CallbackID callbackID)
     RectForCharacterRangeCallback(WebCore::IntRect rect, struct WebKit::EditingRange actualRange, WebKit::CallbackID callbackID)
+#if ENABLE(APPLICATION_MANIFEST)
+    ApplicationManifestCallback(std::optional<WebCore::ApplicationManifest> manifest, WebKit::CallbackID callbackID)
+#endif
 #if PLATFORM(MAC)
     AttributedStringForCharacterRangeCallback(struct WebKit::AttributedString string, struct WebKit::EditingRange actualRange, WebKit::CallbackID callbackID)
     FontAtSelectionCallback(String fontName, double fontSize, bool selectioHasMultipleFonts, WebKit::CallbackID callbackID)
index 0645e7d..d7309f6 100644 (file)
                5CE85B201C88E64B0070BFCE /* PingLoad.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE85B1F1C88E6430070BFCE /* PingLoad.h */; };
                5CFECB041E1ED1CC00F88504 /* LegacyCustomProtocolManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CFECB031E1ED1C800F88504 /* LegacyCustomProtocolManager.cpp */; };
                617A52D81F43A9DA00DCDC0A /* ServiceWorkerClientFetchMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 617A52D71F43A9B600DCDC0A /* ServiceWorkerClientFetchMessageReceiver.cpp */; };
+               63108F961F96719C00A0DB84 /* _WKApplicationManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 63108F941F96719C00A0DB84 /* _WKApplicationManifest.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               63108F971F96719C00A0DB84 /* _WKApplicationManifest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 63108F951F96719C00A0DB84 /* _WKApplicationManifest.mm */; };
+               63108F991F9671F700A0DB84 /* _WKApplicationManifestInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 63108F981F9671F700A0DB84 /* _WKApplicationManifestInternal.h */; };
+               634842511FB26E7100946E3C /* APIApplicationManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 6348424F1FB26E7100946E3C /* APIApplicationManifest.h */; };
                636353A51E9858DF0009F8AF /* _WKGeolocationCoreLocationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FABE191E970D65003011D5 /* _WKGeolocationCoreLocationProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                63C32C251E9810D900699BD0 /* _WKGeolocationPosition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 63C32C231E9810D900699BD0 /* _WKGeolocationPosition.mm */; };
                63C32C261E9810D900699BD0 /* _WKGeolocationPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = 63C32C241E9810D900699BD0 /* _WKGeolocationPosition.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5D442A5516D5856700AC3331 /* PluginService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PluginService.entitlements; sourceTree = "<group>"; };
                5DAD73F1116FF90C00EE5396 /* BaseTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = BaseTarget.xcconfig; sourceTree = "<group>"; };
                617A52D71F43A9B600DCDC0A /* ServiceWorkerClientFetchMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerClientFetchMessageReceiver.cpp; sourceTree = "<group>"; };
+               63108F941F96719C00A0DB84 /* _WKApplicationManifest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKApplicationManifest.h; sourceTree = "<group>"; };
+               63108F951F96719C00A0DB84 /* _WKApplicationManifest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKApplicationManifest.mm; sourceTree = "<group>"; };
+               63108F981F9671F700A0DB84 /* _WKApplicationManifestInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKApplicationManifestInternal.h; sourceTree = "<group>"; };
+               6348424F1FB26E7100946E3C /* APIApplicationManifest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APIApplicationManifest.h; sourceTree = "<group>"; };
                63C32C231E9810D900699BD0 /* _WKGeolocationPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKGeolocationPosition.mm; sourceTree = "<group>"; };
                63C32C241E9810D900699BD0 /* _WKGeolocationPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKGeolocationPosition.h; sourceTree = "<group>"; };
                63C32C271E98119000699BD0 /* _WKGeolocationPositionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKGeolocationPositionInternal.h; sourceTree = "<group>"; };
                                37A5E01218BBF937000A081E /* _WKActivatedElementInfo.h */,
                                37A5E01118BBF937000A081E /* _WKActivatedElementInfo.mm */,
                                379A873518BBFA4300588AF2 /* _WKActivatedElementInfoInternal.h */,
+                               63108F941F96719C00A0DB84 /* _WKApplicationManifest.h */,
+                               63108F951F96719C00A0DB84 /* _WKApplicationManifest.mm */,
+                               63108F981F9671F700A0DB84 /* _WKApplicationManifestInternal.h */,
                                F44291911FA59107002CC93E /* _WKAttachment.h */,
                                F44291931FA59311002CC93E /* _WKAttachment.mm */,
                                F44291951FA5942A002CC93E /* _WKAttachmentInternal.h */,
                                37C4C08318149C2A003688B9 /* Cocoa */,
                                BC8A501311765F4500757573 /* cpp */,
                                BC111B47112F616900337BAB /* mac */,
+                               6348424F1FB26E7100946E3C /* APIApplicationManifest.h */,
                                2E5C770D1FA7D429005932C3 /* APIAttachment.cpp */,
                                2E5C770C1FA7D429005932C3 /* APIAttachment.h */,
                                99C81D5B1C20E817005C4C82 /* APIAutomationClient.h */,
                        files = (
                                37A5E01418BBF93F000A081E /* _WKActivatedElementInfo.h in Headers */,
                                379A873618BBFA4300588AF2 /* _WKActivatedElementInfoInternal.h in Headers */,
+                               63108F961F96719C00A0DB84 /* _WKApplicationManifest.h in Headers */,
+                               63108F991F9671F700A0DB84 /* _WKApplicationManifestInternal.h in Headers */,
                                F44291921FA591C9002CC93E /* _WKAttachment.h in Headers */,
                                F44291961FA5942A002CC93E /* _WKAttachmentInternal.h in Headers */,
                                99E714C51C124A0400665B3A /* _WKAutomationDelegate.h in Headers */,
                                A19DD3C01D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h in Headers */,
                                A182D5B51BE6BD250087A7CC /* AccessibilityIOS.h in Headers */,
                                A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */,
+                               634842511FB26E7100946E3C /* APIApplicationManifest.h in Headers */,
                                BC64697011DBE603006455B0 /* APIArray.h in Headers */,
                                2E5C770E1FA7D429005932C3 /* APIAttachment.h in Headers */,
                                99C81D5D1C21F38B005C4C82 /* APIAutomationClient.h in Headers */,
                        buildActionMask = 2147483647;
                        files = (
                                37A5E01318BBF937000A081E /* _WKActivatedElementInfo.mm in Sources */,
+                               63108F971F96719C00A0DB84 /* _WKApplicationManifest.mm in Sources */,
                                F44291941FA59311002CC93E /* _WKAttachment.mm in Sources */,
                                990D28B21C65209400986977 /* _WKAutomationSession.mm in Sources */,
                                99788ACC1F421DE200C08000 /* _WKAutomationSessionConfiguration.mm in Sources */,
index 7866a77..ab0a56b 100644 (file)
@@ -1840,4 +1840,15 @@ void WebFrameLoaderClient::finishedLoadingIcon(uint64_t callbackIdentifier, Shar
     }
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+void WebFrameLoaderClient::finishedLoadingApplicationManifest(uint64_t callbackIdentifier, const std::optional<WebCore::ApplicationManifest>& manifest)
+{
+    WebPage* webPage = m_frame->page();
+    if (!webPage)
+        return;
+
+    webPage->didFinishLoadingApplicationManifest(callbackIdentifier, manifest);
+}
+#endif // ENABLE(APPLICATION_MANIFEST)
+
 } // namespace WebKit
index 5a22f0d..290d1bb 100644 (file)
@@ -262,6 +262,10 @@ private:
     void getLoadDecisionForIcons(const Vector<std::pair<WebCore::LinkIcon&, uint64_t>>&) final;
     void finishedLoadingIcon(uint64_t callbackIdentifier, WebCore::SharedBuffer*) final;
 
+#if ENABLE(APPLICATION_MANIFEST)
+    void finishedLoadingApplicationManifest(uint64_t, const std::optional<WebCore::ApplicationManifest>&) final;
+#endif
+
     WebFrame* m_frame;
     RefPtr<PluginView> m_pluginView;
     bool m_hasSentResponseToPluginView;
index 519fd52..a918ec6 100644 (file)
@@ -5898,4 +5898,32 @@ RefPtr<HTMLAttachmentElement> WebPage::attachmentElementWithIdentifier(const Str
 
 #endif // ENABLE(ATTACHMENT_ELEMENT)
 
+#if ENABLE(APPLICATION_MANIFEST)
+void WebPage::getApplicationManifest(CallbackID callbackID)
+{
+    ASSERT(callbackID.isValid());
+    Document* mainFrameDocument = m_mainFrame->coreFrame()->document();
+    DocumentLoader* loader = mainFrameDocument ? mainFrameDocument->loader() : nullptr;
+
+    if (!loader) {
+        send(Messages::WebPageProxy::ApplicationManifestCallback(std::nullopt, callbackID));
+        return;
+    }
+
+    auto coreCallbackID = loader->loadApplicationManifest();
+    if (!coreCallbackID) {
+        send(Messages::WebPageProxy::ApplicationManifestCallback(std::nullopt, callbackID));
+        return;
+    }
+
+    m_applicationManifestFetchCallbackMap.add(coreCallbackID, callbackID.toInteger());
+}
+
+void WebPage::didFinishLoadingApplicationManifest(uint64_t coreCallbackID, const std::optional<WebCore::ApplicationManifest>& manifest)
+{
+    auto callbackID = CallbackID::fromInteger(m_applicationManifestFetchCallbackMap.take(coreCallbackID));
+    send(Messages::WebPageProxy::ApplicationManifestCallback(manifest, callbackID));
+}
+#endif // ENABLE(APPLICATION_MANIFEST)
+
 } // namespace WebKit
index f265038..0909125 100644 (file)
 #include <WebCore/ViewportConfiguration.h>
 #endif
 
+#if ENABLE(APPLICATION_MANIFEST)
+#include <WebCore/ApplicationManifest.h>
+#endif
+
 #if ENABLE(IOS_TOUCH_EVENTS)
 #include <WebKitAdditions/PlatformTouchEventIOS.h>
 #elif ENABLE(TOUCH_EVENTS)
@@ -1031,6 +1035,11 @@ public:
     void setAttachmentDataAndContentType(const String& identifier, const IPC::DataReference&, std::optional<String> newContentType, std::optional<String> newFilename, CallbackID);
 #endif
 
+#if ENABLE(APPLICATION_MANIFEST)
+    void getApplicationManifest(CallbackID);
+    void didFinishLoadingApplicationManifest(uint64_t, const std::optional<WebCore::ApplicationManifest>&);
+#endif
+
 private:
     WebPage(uint64_t pageID, WebPageCreationParameters&&);
 
@@ -1645,6 +1654,10 @@ private:
     HashMap<uint64_t, WebURLSchemeHandlerProxy*> m_identifierToURLSchemeHandlerProxyMap;
 
     HashMap<uint64_t, WTF::Function<void (bool granted)>> m_storageAccessResponseCallbackMap;
+
+#if ENABLE(APPLICATION_MANIFEST)
+    HashMap<uint64_t, uint64_t> m_applicationManifestFetchCallbackMap;
+#endif
 };
 
 } // namespace WebKit
index faf4ccb..f2f18cb 100644 (file)
@@ -491,4 +491,8 @@ messages -> WebPage LegacyReceiver {
     SetAttachmentDisplayOptions(String identifier, struct WebCore::AttachmentDisplayOptions options, WebKit::CallbackID callbackID)
     SetAttachmentDataAndContentType(String identifier, IPC::DataReference data, std::optional<String> newContentType, std::optional<String> newFilename, WebKit::CallbackID callbackID)
 #endif
+
+#if ENABLE(APPLICATION_MANIFEST)
+    GetApplicationManifest(WebKit::CallbackID callbackID)
+#endif
 }
index 0c38ab8..3589bdf 100644 (file)
@@ -1,3 +1,34 @@
+2017-12-06  David Quesada  <david_quesada@apple.com>
+
+        [Web App Manifest] Add SPI for fetching the manifest
+        https://bugs.webkit.org/show_bug.cgi?id=180294
+        rdar://problem/34747968
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm: Added.
+            Added two API tests for _WKApplicationManifest:
+            - Testing _WKApplicationManifest's conformance to NSCoding.
+            - Testing -[WKWebView _getApplicationManifestWithCompletionHandler:], verifying the
+              values of the resulting _WKApplicationManifest.
+        (TestWebKitAPI::TEST):
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+            Added a new testRunner method getApplicationManifestThen(), used by the LayoutTests
+            to request the document load its associated manifest. The layout tests formerly called
+            an unimplemented function getManifestThen(), but I added 'Application' to somewhat
+            differentiate this from the app cache manifest.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::didReceiveMessageToPage):
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::getApplicationManifestThen):
+        (WTR::TestRunner::didGetApplicationManifest):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2017-12-05  Stephan Szabo  <stephan.szabo@sony.com>
 
         Switch windows build to Visual Studio 2017
index 300c778..60bde2d 100644 (file)
                6354F4D11F7C3AB500D89DF3 /* ApplicationManifestParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6354F4D01F7C3AB500D89DF3 /* ApplicationManifestParser.cpp */; };
                6356FB221EC4E0BA0044BF18 /* VisibleContentRect.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */; };
                636353A71E98665D0009F8AF /* GeolocationGetCurrentPositionResult.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 636353A61E9861940009F8AF /* GeolocationGetCurrentPositionResult.html */; };
+               63F668221F97F7F90032EE51 /* ApplicationManifest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 63F668201F97C3AA0032EE51 /* ApplicationManifest.mm */; };
                6BFD294C1D5E6C1D008EC968 /* HashCountedSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A38D7E51C752D5F004F157D /* HashCountedSet.cpp */; };
                751B05D61F8EAC410028A09E /* DatabaseTrackerTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */; };
                754CEC811F6722F200D0039A /* AutoFillAvailable.mm in Sources */ = {isa = PBXBuildFile; fileRef = 754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */; };
                6354F4D01F7C3AB500D89DF3 /* ApplicationManifestParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationManifestParser.cpp; sourceTree = "<group>"; };
                6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = VisibleContentRect.mm; sourceTree = "<group>"; };
                636353A61E9861940009F8AF /* GeolocationGetCurrentPositionResult.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = GeolocationGetCurrentPositionResult.html; sourceTree = "<group>"; };
+               63F668201F97C3AA0032EE51 /* ApplicationManifest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ApplicationManifest.mm; sourceTree = "<group>"; };
                751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DatabaseTrackerTest.mm; sourceTree = "<group>"; };
                754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoFillAvailable.mm; sourceTree = "<group>"; };
                7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheAddImageToCacheIOS.mm; sourceTree = "<group>"; };
                                37E7DD651EA0715B009B396D /* AdditionalReadAccessAllowedURLsProtocol.h */,
                                A1DF74301C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm */,
                                2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */,
+                               63F668201F97C3AA0032EE51 /* ApplicationManifest.mm */,
                                754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */,
                                2DD355351BD08378005DF4A7 /* AutoLayoutIntegration.mm */,
                                374B7A5E1DF36EEE00ACCB6C /* BundleEditingDelegate.mm */,
                                7A909A7D1D877480007E10F8 /* AffineTransform.cpp in Sources */,
                                A1DF74321C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm in Sources */,
                                2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */,
+                               63F668221F97F7F90032EE51 /* ApplicationManifest.mm in Sources */,
                                6354F4D11F7C3AB500D89DF3 /* ApplicationManifestParser.cpp in Sources */,
                                7CCE7EB41A411A7E00447C4C /* AttributedString.mm in Sources */,
                                CDC8E48D1BC5CB4500594FEC /* AudioSessionCategoryIOS.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm
new file mode 100644 (file)
index 0000000..710a77a
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 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"
+
+#if WK_API_ENABLED && ENABLE(APPLICATION_MANIFEST)
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import "TestNavigationDelegate.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKApplicationManifest.h>
+
+namespace TestWebKitAPI {
+
+TEST(WebKit, ApplicationManifestCoding)
+{
+    auto jsonString = @"{ \"name\": \"TestName\", \"short_name\": \"TestShortName\", \"description\": \"TestDescription\", \"scope\": \"https://test.com/app\", \"start_url\": \"https://test.com/app/index.html\" }";
+    RetainPtr<_WKApplicationManifest> manifest { [_WKApplicationManifest applicationManifestFromJSON:jsonString manifestURL:[NSURL URLWithString:@"https://test.com/manifest.json"] documentURL:[NSURL URLWithString:@"https://test.com/"]] };
+    
+    manifest = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:manifest.get()]];
+    
+    EXPECT_TRUE([manifest isKindOfClass:[_WKApplicationManifest class]]);
+    EXPECT_STREQ("TestName", manifest.get().name.UTF8String);
+    EXPECT_STREQ("TestShortName", manifest.get().shortName.UTF8String);
+    EXPECT_STREQ("TestDescription", manifest.get().applicationDescription.UTF8String);
+    EXPECT_STREQ("https://test.com/app", manifest.get().scope.absoluteString.UTF8String);
+    EXPECT_STREQ("https://test.com/app/index.html", manifest.get().startURL.absoluteString.UTF8String);
+}
+
+TEST(WebKit, ApplicationManifestBasic)
+{
+    static bool done = false;
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]);
+    [webView synchronouslyLoadHTMLString:@""];
+    [webView.get() _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) {
+        EXPECT_NULL(manifest);
+        done = true;
+    }];
+    Util::run(&done);
+
+    done = false;
+    [webView synchronouslyLoadHTMLString:@"<link rel=\"manifest\" href=\"invalidurl://path\">"];
+    [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) {
+        EXPECT_NULL(manifest);
+        done = true;
+    }];
+    Util::run(&done);
+
+    done = false;
+    NSDictionary *manifestObject = @{ @"name": @"Test" };
+    [webView synchronouslyLoadHTMLString:[NSString stringWithFormat:@"<link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\">", [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]]];
+    [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) {
+        EXPECT_TRUE([manifest.name isEqualToString:@"Test"]);
+        done = true;
+    }];
+    Util::run(&done);
+
+    done = false;
+    manifestObject = @{
+        @"name": @"A Web Application",
+        @"short_name": @"WebApp",
+        @"description": @"Hello.",
+        @"start_url": @"http://example.com/app/start",
+        @"scope": @"http://example.com/app",
+    };
+    NSString *htmlString = [NSString stringWithFormat:@"<link rel=\"manifest\" href=\"data:text/plain;charset=utf-8;base64,%@\">", [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]];
+    [webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:@"http://example.com/app/index"]];
+    [webView _test_waitForDidFinishNavigation];
+    [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) {
+        EXPECT_TRUE([manifest.name isEqualToString:@"A Web Application"]);
+        EXPECT_TRUE([manifest.shortName isEqualToString:@"WebApp"]);
+        EXPECT_TRUE([manifest.applicationDescription isEqualToString:@"Hello."]);
+        EXPECT_TRUE([manifest.startURL isEqual:[NSURL URLWithString:@"http://example.com/app/start"]]);
+        EXPECT_TRUE([manifest.scope isEqual:[NSURL URLWithString:@"http://example.com/app"]]);
+        done = true;
+    }];
+    Util::run(&done);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // WK_API_ENABLED && ENABLE(APPLICATION_MANIFEST)
index 332fe26..a8bc7cb 100644 (file)
@@ -306,4 +306,6 @@ interface TestRunner {
     void terminateNetworkProcess();
 
     void removeAllSessionCredentials(object callback);
+
+    void getApplicationManifestThen(object callback);
 };
index c9339f0..56b0dcd 100644 (file)
@@ -298,6 +298,11 @@ void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef m
         return;
     }
     
+    if (WKStringIsEqualToUTF8CString(messageName, "DidGetApplicationManifest")) {
+        m_testRunner->didGetApplicationManifest();
+        return;
+    }
+    
     WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
     WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
     WKBundlePagePostMessage(page, errorMessageName.get(), errorMessageBody.get());
index cb5670b..aa98d0c 100644 (file)
@@ -652,6 +652,7 @@ enum {
     StatisticsDidRunTelemetryCallbackID,
     StatisticsDidClearThroughWebsiteDataRemovalCallbackID,
     DidRemoveAllSessionCredentialsCallbackID,
+    GetApplicationManifestCallbackID,
     FirstUIScriptCallbackID = 100
 };
 
@@ -1874,4 +1875,17 @@ uint64_t TestRunner::domCacheSize(JSStringRef origin)
     return WKUInt64GetValue(static_cast<WKUInt64Ref>(returnData));
 }
 
+void TestRunner::getApplicationManifestThen(JSValueRef callback)
+{
+    cacheTestRunnerCallback(GetApplicationManifestCallbackID, callback);
+    
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("GetApplicationManifest"));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr);
+}
+
+void TestRunner::didGetApplicationManifest()
+{
+    callTestRunnerCallback(GetApplicationManifestCallbackID);
+}
+
 } // namespace WTR
index d36910d..d644943 100644 (file)
@@ -405,6 +405,9 @@ public:
 
     void removeAllSessionCredentials(JSValueRef);
     void callDidRemoveAllSessionCredentialsCallback();
+    
+    void getApplicationManifestThen(JSValueRef);
+    void didGetApplicationManifest();
 
 private:
     TestRunner();
index 2ca7e52..75372e7 100644 (file)
@@ -1246,6 +1246,19 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
         return result;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "GetApplicationManifest")) {
+#ifdef __BLOCKS__
+        WKPageGetApplicationManifest_b(TestController::singleton().mainWebView()->page(), ^{
+            WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DidGetApplicationManifest"));
+            WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+        });
+#else
+        // FIXME: Add API for loading the manifest on non-__BLOCKS__ ports.
+        ASSERT_NOT_REACHED();
+#endif
+        return nullptr;
+    }
+
     ASSERT_NOT_REACHED();
     return nullptr;
 }