Title: [225989] trunk
Revision
225989
Author
[email protected]
Date
2017-12-15 15:14:33 -0800 (Fri, 15 Dec 2017)

Log Message

Introduce SPI _WKWebsitePolicies.websiteDataStore
https://bugs.webkit.org/show_bug.cgi?id=180880
<rdar://problem/35535328>

Reviewed by Andy Estes.

Source/WebKit:

The SPI doesn't do anything yet, but it already has some restrictions and tests!
WKWebView._updateWebsitePolicies can't be used to update a WKWebsiteDataStore.  Only during navigation.
Even during navigation, we are only supporting the default and ephemeral data stores right now.
This functionality won't be supported in the C API.  This is enforced with RELEASE_ASSERTs.
If we change our minds, we can change them and add restrictions similar to the ObjC restrictions.

* Shared/WebsitePoliciesData.cpp:
(WebKit::WebsitePoliciesData::encode const):
(WebKit::WebsitePoliciesData::decode):
* Shared/WebsitePoliciesData.h:
* UIProcess/API/APIWebsitePolicies.cpp:
(API::WebsitePolicies::WebsitePolicies):
(API::WebsitePolicies::setWebsiteDataStore):
(API::WebsitePolicies::data):
* UIProcess/API/APIWebsitePolicies.h:
* UIProcess/API/C/WKFramePolicyListener.cpp:
(WKFramePolicyListenerUseWithPolicies):
* UIProcess/API/C/WKPage.cpp:
(WKPageUpdateWebsitePolicies):
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _updateWebsitePolicies:]):
* UIProcess/API/Cocoa/_WKWebsitePolicies.h:
* UIProcess/API/Cocoa/_WKWebsitePolicies.mm:
(-[_WKWebsitePolicies websiteDataStore]):
(-[_WKWebsitePolicies setWebsiteDataStore:]):
* UIProcess/Cocoa/NavigationState.mm:
(WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
(-[WebsitePoliciesWebsiteDataStoreDelegate _webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[WebsitePoliciesWebsiteDataStoreDelegate webView:startURLSchemeTask:]):
(-[WebsitePoliciesWebsiteDataStoreDelegate webView:stopURLSchemeTask:]):
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (225988 => 225989)


--- trunk/Source/WebKit/ChangeLog	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/ChangeLog	2017-12-15 23:14:33 UTC (rev 225989)
@@ -1,5 +1,41 @@
 2017-12-15  Alex Christensen  <[email protected]>
 
+        Introduce SPI _WKWebsitePolicies.websiteDataStore
+        https://bugs.webkit.org/show_bug.cgi?id=180880
+        <rdar://problem/35535328>
+
+        Reviewed by Andy Estes.
+
+        The SPI doesn't do anything yet, but it already has some restrictions and tests!
+        WKWebView._updateWebsitePolicies can't be used to update a WKWebsiteDataStore.  Only during navigation.
+        Even during navigation, we are only supporting the default and ephemeral data stores right now.
+        This functionality won't be supported in the C API.  This is enforced with RELEASE_ASSERTs.
+        If we change our minds, we can change them and add restrictions similar to the ObjC restrictions.
+
+        * Shared/WebsitePoliciesData.cpp:
+        (WebKit::WebsitePoliciesData::encode const):
+        (WebKit::WebsitePoliciesData::decode):
+        * Shared/WebsitePoliciesData.h:
+        * UIProcess/API/APIWebsitePolicies.cpp:
+        (API::WebsitePolicies::WebsitePolicies):
+        (API::WebsitePolicies::setWebsiteDataStore):
+        (API::WebsitePolicies::data):
+        * UIProcess/API/APIWebsitePolicies.h:
+        * UIProcess/API/C/WKFramePolicyListener.cpp:
+        (WKFramePolicyListenerUseWithPolicies):
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageUpdateWebsitePolicies):
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _updateWebsitePolicies:]):
+        * UIProcess/API/Cocoa/_WKWebsitePolicies.h:
+        * UIProcess/API/Cocoa/_WKWebsitePolicies.mm:
+        (-[_WKWebsitePolicies websiteDataStore]):
+        (-[_WKWebsitePolicies setWebsiteDataStore:]):
+        * UIProcess/Cocoa/NavigationState.mm:
+        (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):
+
+2017-12-15  Alex Christensen  <[email protected]>
+
         Fix GTK build.
 
         * UIProcess/API/glib/WebKitPolicyDecision.cpp:

Modified: trunk/Source/WebKit/Shared/WebsitePoliciesData.cpp (225988 => 225989)


--- trunk/Source/WebKit/Shared/WebsitePoliciesData.cpp	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/Shared/WebsitePoliciesData.cpp	2017-12-15 23:14:33 UTC (rev 225989)
@@ -37,6 +37,7 @@
     encoder << autoplayPolicy;
     encoder << allowedAutoplayQuirks;
     encoder << customHeaderFields;
+    encoder << websiteDataStoreParameters;
 }
 
 std::optional<WebsitePoliciesData> WebsitePoliciesData::decode(IPC::Decoder& decoder)
@@ -61,11 +62,17 @@
     if (!customHeaderFields)
         return std::nullopt;
     
+    std::optional<std::optional<WebsiteDataStoreParameters>> websiteDataStoreParameters;
+    decoder >> websiteDataStoreParameters;
+    if (!websiteDataStoreParameters)
+        return std::nullopt;
+    
     return { {
         WTFMove(*contentBlockersEnabled),
         WTFMove(*allowedAutoplayQuirks),
         WTFMove(*autoplayPolicy),
         WTFMove(*customHeaderFields),
+        WTFMove(*websiteDataStoreParameters),
     } };
 }
 

Modified: trunk/Source/WebKit/Shared/WebsitePoliciesData.h (225988 => 225989)


--- trunk/Source/WebKit/Shared/WebsitePoliciesData.h	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/Shared/WebsitePoliciesData.h	2017-12-15 23:14:33 UTC (rev 225989)
@@ -27,6 +27,7 @@
 
 #include "WebsiteAutoplayPolicy.h"
 #include "WebsiteAutoplayQuirk.h"
+#include "WebsiteDataStoreParameters.h"
 #include <WebCore/HTTPHeaderField.h>
 #include <wtf/OptionSet.h>
 
@@ -48,6 +49,7 @@
     OptionSet<WebsiteAutoplayQuirk> allowedAutoplayQuirks;
     WebsiteAutoplayPolicy autoplayPolicy { WebsiteAutoplayPolicy::Default };
     Vector<WebCore::HTTPHeaderField> customHeaderFields;
+    std::optional<WebsiteDataStoreParameters> websiteDataStoreParameters;
     
     void encode(IPC::Encoder&) const;
     static std::optional<WebsitePoliciesData> decode(IPC::Decoder&);

Modified: trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp	2017-12-15 23:14:33 UTC (rev 225989)
@@ -26,17 +26,36 @@
 #include "config.h"
 #include "APIWebsitePolicies.h"
 
+#include "APIWebsiteDataStore.h"
 #include "WebsitePoliciesData.h"
 
 namespace API {
 
+WebsitePolicies::WebsitePolicies() = default;
+
+WebsitePolicies::WebsitePolicies(bool contentBlockersEnabled, OptionSet<WebKit::WebsiteAutoplayQuirk> allowedAutoplayQuirks, WebKit::WebsiteAutoplayPolicy autoplayPolicy, Vector<WebCore::HTTPHeaderField>&& customHeaderFields, RefPtr<WebsiteDataStore>&& websiteDataStore)
+    : m_contentBlockersEnabled(contentBlockersEnabled)
+    , m_allowedAutoplayQuirks(allowedAutoplayQuirks)
+    , m_autoplayPolicy(autoplayPolicy)
+    , m_customHeaderFields(WTFMove(customHeaderFields))
+    , m_websiteDataStore(WTFMove(websiteDataStore))
+{ }
+
 WebsitePolicies::~WebsitePolicies()
 {
 }
 
+void WebsitePolicies::setWebsiteDataStore(RefPtr<WebsiteDataStore>&& websiteDataStore)
+{
+    m_websiteDataStore = WTFMove(websiteDataStore);
+}
+
 WebKit::WebsitePoliciesData WebsitePolicies::data()
 {
-    return { contentBlockersEnabled(), allowedAutoplayQuirks(), autoplayPolicy(), customHeaderFields() };
+    std::optional<WebKit::WebsiteDataStoreParameters> parameters;
+    if (m_websiteDataStore)
+        parameters = m_websiteDataStore->websiteDataStore().parameters();
+    return { contentBlockersEnabled(), allowedAutoplayQuirks(), autoplayPolicy(), customHeaderFields(), WTFMove(parameters) };
 }
 
 }

Modified: trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h	2017-12-15 23:14:33 UTC (rev 225989)
@@ -40,10 +40,12 @@
 
 namespace API {
 
+class WebsiteDataStore;
+
 class WebsitePolicies final : public API::ObjectImpl<API::Object::Type::WebsitePolicies> {
 public:
     static Ref<WebsitePolicies> create() { return adoptRef(*new WebsitePolicies); }
-    WebsitePolicies() = default;
+    WebsitePolicies();
     ~WebsitePolicies();
 
     bool contentBlockersEnabled() const { return m_contentBlockersEnabled; }
@@ -58,21 +60,20 @@
     const Vector<WebCore::HTTPHeaderField>& customHeaderFields() const { return m_customHeaderFields; }
     Vector<WebCore::HTTPHeaderField>&& takeCustomHeaderFields() { return WTFMove(m_customHeaderFields); }
     void setCustomHeaderFields(Vector<WebCore::HTTPHeaderField>&& fields) { m_customHeaderFields = WTFMove(fields); }
+    
+    WebsiteDataStore* websiteDataStore() const { return m_websiteDataStore.get(); }
+    void setWebsiteDataStore(RefPtr<WebsiteDataStore>&&);
 
     WebKit::WebsitePoliciesData data();
 
 private:
-    WebsitePolicies(bool contentBlockersEnabled, OptionSet<WebKit::WebsiteAutoplayQuirk> allowedAutoplayQuirks, WebKit::WebsiteAutoplayPolicy autoplayPolicy, Vector<WebCore::HTTPHeaderField>&& customHeaderFields)
-        : m_contentBlockersEnabled(contentBlockersEnabled)
-        , m_allowedAutoplayQuirks(allowedAutoplayQuirks)
-        , m_autoplayPolicy(autoplayPolicy)
-        , m_customHeaderFields(WTFMove(customHeaderFields))
-    { }
+    WebsitePolicies(bool contentBlockersEnabled, OptionSet<WebKit::WebsiteAutoplayQuirk>, WebKit::WebsiteAutoplayPolicy, Vector<WebCore::HTTPHeaderField>&&, RefPtr<WebsiteDataStore>&&);
 
     bool m_contentBlockersEnabled { true };
     OptionSet<WebKit::WebsiteAutoplayQuirk> m_allowedAutoplayQuirks;
     WebKit::WebsiteAutoplayPolicy m_autoplayPolicy { WebKit::WebsiteAutoplayPolicy::Default };
     Vector<WebCore::HTTPHeaderField> m_customHeaderFields;
+    RefPtr<WebsiteDataStore> m_websiteDataStore;
 };
 
 } // namespace API

Modified: trunk/Source/WebKit/UIProcess/API/C/WKFramePolicyListener.cpp (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/C/WKFramePolicyListener.cpp	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/C/WKFramePolicyListener.cpp	2017-12-15 23:14:33 UTC (rev 225989)
@@ -46,7 +46,9 @@
 
 void WKFramePolicyListenerUseWithPolicies(WKFramePolicyListenerRef policyListenerRef, WKWebsitePoliciesRef websitePolicies)
 {
-    toImpl(policyListenerRef)->use(toImpl(websitePolicies)->data());
+    auto data = ""
+    RELEASE_ASSERT_WITH_MESSAGE(!data.websiteDataStoreParameters, "Setting WebsitePolicies.WebsiteDataStore is not supported in the C API.");
+    toImpl(policyListenerRef)->use(WTFMove(data));
 }
 
 void WKFramePolicyListenerDownload(WKFramePolicyListenerRef policyListenerRef)

Modified: trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp	2017-12-15 23:14:33 UTC (rev 225989)
@@ -325,7 +325,9 @@
 
 void WKPageUpdateWebsitePolicies(WKPageRef pageRef, WKWebsitePoliciesRef websitePoliciesRef)
 {
-    toImpl(pageRef)->updateWebsitePolicies(toImpl(websitePoliciesRef)->data());
+    auto data = ""
+    RELEASE_ASSERT_WITH_MESSAGE(!data.websiteDataStoreParameters, "Setting WebsitePolicies.WebsiteDataStore is not supported in the C API.");
+    toImpl(pageRef)->updateWebsitePolicies(WTFMove(data));
 }
 
 WKStringRef WKPageCopyTitle(WKPageRef pageRef)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2017-12-15 23:14:33 UTC (rev 225989)
@@ -4238,7 +4238,10 @@
 
 - (void)_updateWebsitePolicies:(_WKWebsitePolicies *)websitePolicies
 {
-    _page->updateWebsitePolicies(websitePolicies->_websitePolicies->data());
+    auto data = ""
+    if (data.websiteDataStoreParameters)
+        [NSException raise:NSInvalidArgumentException format:@"Updating WKWebsiteDataStore is only supported during decidePolicyForNavigationAction."];
+    _page->updateWebsitePolicies(WTFMove(data));
 }
 
 - (BOOL)_allowsRemoteInspection

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h	2017-12-15 23:14:33 UTC (rev 225989)
@@ -40,6 +40,8 @@
     _WKWebsiteAutoplayQuirkArbitraryUserGestures = 1 << 2,
 } WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 
+@class WKWebsiteDataStore;
+
 WK_CLASS_AVAILABLE(macosx(10.12.3), ios(10.3))
 @interface _WKWebsitePolicies : NSObject
 
@@ -47,6 +49,7 @@
 @property (nonatomic) _WKWebsiteAutoplayQuirk allowedAutoplayQuirks WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 @property (nonatomic) _WKWebsiteAutoplayPolicy autoplayPolicy WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 @property (nonatomic, copy) NSDictionary<NSString *, NSString *> *customHeaderFields WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, strong) WKWebsiteDataStore *websiteDataStore WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm	2017-12-15 23:14:33 UTC (rev 225989)
@@ -146,6 +146,17 @@
     _websitePolicies->setCustomHeaderFields(WTFMove(parsedFields));
 }
 
+- (WKWebsiteDataStore *)websiteDataStore
+{
+    auto* store = _websitePolicies->websiteDataStore();
+    return store ? WebKit::wrapper(*store) : nil;
+}
+
+- (void)setWebsiteDataStore:(WKWebsiteDataStore *)websiteDataStore
+{
+    _websitePolicies->setWebsiteDataStore(websiteDataStore->_websiteDataStore.get());
+}
+
 - (NSString *)description
 {
     return [NSString stringWithFormat:@"<%@: %p; contentBlockersEnabled = %d>", NSStringFromClass(self.class), self, self.contentBlockersEnabled];

Modified: trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm (225988 => 225989)


--- trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm	2017-12-15 23:14:33 UTC (rev 225989)
@@ -466,8 +466,14 @@
         checker->didCallCompletionHandler();
 
         std::optional<WebsitePoliciesData> data;
-        if (websitePolicies)
+        if (websitePolicies) {
             data = ""
+            if (data->websiteDataStoreParameters) {
+                auto& sessionID = data->websiteDataStoreParameters->networkSessionParameters.sessionID;
+                if (!sessionID.isEphemeral() && sessionID != PAL::SessionID::defaultSessionID())
+                    [NSException raise:NSInvalidArgumentException format:@"_WKWebsitePolicies.websiteDataStore must be nil, default, or non-persistent."];
+            }
+        }
 
         switch (actionPolicy) {
         case WKNavigationActionPolicyAllow:

Modified: trunk/Tools/ChangeLog (225988 => 225989)


--- trunk/Tools/ChangeLog	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Tools/ChangeLog	2017-12-15 23:14:33 UTC (rev 225989)
@@ -1,3 +1,17 @@
+2017-12-15  Alex Christensen  <[email protected]>
+
+        Introduce SPI _WKWebsitePolicies.websiteDataStore
+        https://bugs.webkit.org/show_bug.cgi?id=180880
+        <rdar://problem/35535328>
+
+        Reviewed by Andy Estes.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
+        (-[WebsitePoliciesWebsiteDataStoreDelegate _webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (-[WebsitePoliciesWebsiteDataStoreDelegate webView:startURLSchemeTask:]):
+        (-[WebsitePoliciesWebsiteDataStoreDelegate webView:stopURLSchemeTask:]):
+        (TEST):
+
 2017-12-15  Nael Ouedraogo  <[email protected]>
 
         [GTK] Add proxy option to Minibrowser

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm (225988 => 225989)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm	2017-12-15 22:48:19 UTC (rev 225988)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm	2017-12-15 23:14:33 UTC (rev 225989)
@@ -34,7 +34,9 @@
 #import <WebKit/WKURLSchemeTaskPrivate.h>
 #import <WebKit/WKUserContentControllerPrivate.h>
 #import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/WKWebsiteDataStorePrivate.h>
 #import <WebKit/_WKUserContentExtensionStorePrivate.h>
+#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <WebKit/_WKWebsitePolicies.h>
 #import <wtf/MainThread.h>
 #import <wtf/RetainPtr.h>
@@ -785,5 +787,63 @@
     TestWebKitAPI::Util::run(&fourthTestDone);
 }
 
+static bool done;
 
+@interface WebsitePoliciesWebsiteDataStoreDelegate : NSObject <WKNavigationDelegatePrivate, WKURLSchemeHandler>
+@end
+
+@implementation WebsitePoliciesWebsiteDataStoreDelegate
+
+- (void)_webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy, _WKWebsitePolicies *))decisionHandler
+{
+    if ([navigationAction.request.URL.path isEqualToString:@"/invalid"]) {
+        _WKWebsitePolicies *websitePolicies = [[[_WKWebsitePolicies alloc] init] autorelease];
+        websitePolicies.websiteDataStore = [[[WKWebsiteDataStore alloc] _initWithConfiguration:[[[_WKWebsiteDataStoreConfiguration alloc] init] autorelease]] autorelease];
+
+        bool sawException = false;
+        @try {
+            decisionHandler(WKNavigationActionPolicyAllow, websitePolicies);
+        } @catch (NSException *exception) {
+            sawException = true;
+        }
+        EXPECT_TRUE(sawException);
+
+        done = true;
+    }
+}
+
+- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask
+{
+}
+
+- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask
+{
+}
+
+@end
+
+TEST(WebKit, UpdateWebsitePoliciesInvalid)
+{
+    auto delegate = adoptNS([[WebsitePoliciesWebsiteDataStoreDelegate alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [configuration setURLSchemeHandler:delegate.get() forURLScheme:@"test"];
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    auto policies = adoptNS([[_WKWebsitePolicies alloc] init]);
+    [policies setWebsiteDataStore:[WKWebsiteDataStore nonPersistentDataStore]];
+    bool sawException = false;
+    @try {
+        [webView _updateWebsitePolicies:policies.get()];
+    } @catch (NSException *exception) {
+        sawException = true;
+    }
+    EXPECT_TRUE(sawException);
+    
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///invalid"]]];
+    TestWebKitAPI::Util::run(&done);
+}
+
+// FIXME: Use _WKWebsitePolicies.websiteDataStore and test that it is used.
+
 #endif // WK_API_ENABLED
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to