Commit 894769b0 authored by Victor Costan's avatar Victor Costan Committed by Commit Bot

Async Cookies: Expose oncookiechange on ServiceWorkerGlobalScope.

cookiechange events have been dispatched to ServiceWorkerGlobalScope
since https://crrev.com/c/979334 landed, and can be observed using
addEventListener, as shown by the WPT test at
cookie-store/serviceworker_cookieStore_subscriptions_basic.tentative.https.html

This CL adds the oncookiechange attribute to ServiceWorkerGlobalScope,
allowing the event to be handled by a DOM0-style event handler.

Bug: 729800
Change-Id: Ic27979d94934abf833c116787cdad5243422324b
Reviewed-on: https://chromium-review.googlesource.com/1123766
Commit-Queue: Victor Costan <pwnall@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarJoshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572400}
parent a5adc4ec
...@@ -103,8 +103,8 @@ promise_test(async testCase => { ...@@ -103,8 +103,8 @@ promise_test(async testCase => {
assert_true(event instanceof ExtendableCookieChangeEvent); assert_true(event instanceof ExtendableCookieChangeEvent);
assert_true(event instanceof ExtendableEvent); assert_true(event instanceof ExtendableEvent);
await async_cleanup(() => { await async_cleanup(async () => {
cookieStore.delete('cookie-name'); await cookieStore.delete('cookie-name');
g_cookie_changes = []; g_cookie_changes = [];
RearmCookieChangeReceivedPromise(); RearmCookieChangeReceivedPromise();
}); });
......
...@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js"); ...@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => { self.addEventListener('install', (event) => {
event.waitUntil((async () => { event.waitUntil((async () => {
cookieStore.subscribeToChanges([ await cookieStore.subscribeToChanges([
{ name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]); { name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]);
})()); })());
}); });
...@@ -57,7 +57,8 @@ promise_test(async testCase => { ...@@ -57,7 +57,8 @@ promise_test(async testCase => {
assert_true(event instanceof ExtendableCookieChangeEvent); assert_true(event instanceof ExtendableCookieChangeEvent);
assert_true(event instanceof ExtendableEvent); assert_true(event instanceof ExtendableEvent);
await async_cleanup(() => { cookieStore.delete('cookie-name'); }); await async_cleanup(() => cookieStore.delete('cookie-name'));
}, 'cookiechange dispatched with cookie change that matches subscription'); }, 'cookiechange dispatched with cookie change that matches subscription ' +
'to event handler registered with addEventListener');
done(); done();
...@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js"); ...@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => { self.addEventListener('install', (event) => {
event.waitUntil((async () => { event.waitUntil((async () => {
cookieStore.subscribeToChanges([]); await cookieStore.subscribeToChanges([]);
})()); })());
}); });
......
self.GLOBAL = {
isWindow: function() { return false; },
isWorker: function() { return true; },
};
importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => {
event.waitUntil((async () => {
await cookieStore.subscribeToChanges([
{ name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]);
})());
});
// Workaround because add_cleanup doesn't support async functions yet.
// See https://github.com/web-platform-tests/wpt/issues/6075
async function async_cleanup(cleanup_function) {
try {
await cleanup_function();
} catch (e) {
// Errors in cleanup functions shouldn't result in test failures.
}
}
// Resolves when the service worker receives the 'activate' event.
const kServiceWorkerActivatedPromise = new Promise(resolve => {
self.addEventListener('activate', event => { resolve(); });
});
promise_test(async testCase => {
await kServiceWorkerActivatedPromise;
const cookie_change_received_promise = new Promise((resolve) => {
self.oncookiechange = (event) => { resolve(event); };
});
await cookieStore.set('cookie-name', 'cookie-value');
const event = await cookie_change_received_promise;
assert_equals(event.type, 'cookiechange');
assert_equals(event.changed.length, 1);
assert_equals(event.changed[0].name, 'cookie-name');
assert_equals(event.changed[0].value, 'cookie-value');
assert_equals(event.deleted.length, 0);
assert_true(event instanceof ExtendableCookieChangeEvent);
assert_true(event instanceof ExtendableEvent);
await async_cleanup(() => cookieStore.delete('cookie-name'));
}, 'cookiechange dispatched with cookie change that matches subscription ' +
'to event handler registered with oncookiechange');
done();
<!doctype html>
<meta charset="utf-8">
<title>Async Cookies: oncookiechange event handler attribute in ServiceWorker</title>
<link rel="help" href="https://github.com/WICG/cookie-store">
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
(async () => {
const scope = 'scope';
let registration = await navigator.serviceWorker.getRegistration(scope);
if (registration)
await registration.unregister();
registration = await navigator.serviceWorker.register(
'serviceworker_cookieStore_subscriptions_eventhandler_attribute.js', {scope});
fetch_tests_from_worker(registration.installing);
})();
</script>
...@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js"); ...@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => { self.addEventListener('install', (event) => {
event.waitUntil((async () => { event.waitUntil((async () => {
cookieStore.subscribeToChanges([ await cookieStore.subscribeToChanges([
{ name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]); { name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]);
})()); })());
}); });
...@@ -44,9 +44,9 @@ promise_test(async testCase => { ...@@ -44,9 +44,9 @@ promise_test(async testCase => {
assert_equals(event.changed[0].name, 'cookie-name'); assert_equals(event.changed[0].name, 'cookie-name');
assert_equals(event.changed[0].value, 'cookie-value'); assert_equals(event.changed[0].value, 'cookie-value');
await async_cleanup(() => { await async_cleanup(async () => {
cookieStore.delete('another-cookie-name'); await cookieStore.delete('another-cookie-name');
cookieStore.delete('cookie-name'); await cookieStore.delete('cookie-name');
}); });
}, 'cookiechange not dispatched for change that does not match subscription'); }, 'cookiechange not dispatched for change that does not match subscription');
......
...@@ -108,4 +108,5 @@ partial interface Window { ...@@ -108,4 +108,5 @@ partial interface Window {
partial interface ServiceWorkerGlobalScope { partial interface ServiceWorkerGlobalScope {
[Replaceable, SameObject] readonly attribute CookieStore cookieStore; [Replaceable, SameObject] readonly attribute CookieStore cookieStore;
attribute EventHandler oncookiechange;
}; };
...@@ -2623,6 +2623,7 @@ interface WritableStream ...@@ -2623,6 +2623,7 @@ interface WritableStream
getter onbackgroundfetched getter onbackgroundfetched
getter onbackgroundfetchfail getter onbackgroundfetchfail
getter oncanmakepayment getter oncanmakepayment
getter oncookiechange
getter onfetch getter onfetch
getter oninstall getter oninstall
getter onmessage getter onmessage
...@@ -2643,6 +2644,7 @@ interface WritableStream ...@@ -2643,6 +2644,7 @@ interface WritableStream
setter onbackgroundfetched setter onbackgroundfetched
setter onbackgroundfetchfail setter onbackgroundfetchfail
setter oncanmakepayment setter oncanmakepayment
setter oncookiechange
setter onfetch setter onfetch
setter oninstall setter oninstall
setter onmessage setter onmessage
......
...@@ -12,8 +12,11 @@ blink_modules_sources("cookie_store") { ...@@ -12,8 +12,11 @@ blink_modules_sources("cookie_store") {
"cookie_store.h", "cookie_store.h",
"extendable_cookie_change_event.cc", "extendable_cookie_change_event.cc",
"extendable_cookie_change_event.h", "extendable_cookie_change_event.h",
"global_cookie_store.cc", "global_cookie_store_impl.h",
"global_cookie_store.h", "service_worker_global_scope_cookie_store.cc",
"service_worker_global_scope_cookie_store.h",
"window_cookie_store.cc",
"window_cookie_store.h",
] ]
deps = [ deps = [
......
// Copyright 2017 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/modules/cookie_store/global_cookie_store.h" #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_IMPL_H_
#include <utility> #include <utility>
#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/modules/cookie_store/cookie_store.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_store.h"
#include "third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/supplementable.h"
namespace blink { namespace blink {
namespace {
template <typename T> template <typename T>
class GlobalCookieStoreImpl final class GlobalCookieStoreImpl final
: public GarbageCollected<GlobalCookieStoreImpl<T>>, : public GarbageCollected<GlobalCookieStoreImpl<T>>,
...@@ -67,48 +61,11 @@ class GlobalCookieStoreImpl final ...@@ -67,48 +61,11 @@ class GlobalCookieStoreImpl final
Member<CookieStore> cookie_store_; Member<CookieStore> cookie_store_;
}; };
template <>
CookieStore* GlobalCookieStoreImpl<LocalDOMWindow>::BuildCookieStore(
ExecutionContext* execution_context,
service_manager::InterfaceProvider* interface_provider) {
network::mojom::blink::RestrictedCookieManagerPtr cookie_manager_ptr;
interface_provider->GetInterface(mojo::MakeRequest(&cookie_manager_ptr));
return CookieStore::Create(execution_context, std::move(cookie_manager_ptr),
blink::mojom::blink::CookieStorePtr());
}
template <>
CookieStore* GlobalCookieStoreImpl<WorkerGlobalScope>::BuildCookieStore(
ExecutionContext* execution_context,
service_manager::InterfaceProvider* interface_provider) {
network::mojom::blink::RestrictedCookieManagerPtr cookie_manager_ptr;
interface_provider->GetInterface(mojo::MakeRequest(&cookie_manager_ptr));
blink::mojom::blink::CookieStorePtr cookie_store_ptr;
interface_provider->GetInterface(mojo::MakeRequest(&cookie_store_ptr));
return CookieStore::Create(execution_context, std::move(cookie_manager_ptr),
std::move(cookie_store_ptr));
}
// static // static
template <typename T> template <typename T>
const char GlobalCookieStoreImpl<T>::kSupplementName[] = const char GlobalCookieStoreImpl<T>::kSupplementName[] =
"GlobalCookieStoreImpl"; "GlobalCookieStoreImpl";
} // namespace
CookieStore* GlobalCookieStore::cookieStore(LocalDOMWindow& window) {
return GlobalCookieStoreImpl<LocalDOMWindow>::From(window).GetCookieStore(
window);
}
CookieStore* GlobalCookieStore::cookieStore(ServiceWorkerGlobalScope& worker) {
// ServiceWorkerGlobalScope is Supplementable<WorkerGlobalScope>, not
// Supplementable<ServiceWorkerGlobalScope>.
return GlobalCookieStoreImpl<WorkerGlobalScope>::From(worker).GetCookieStore(
worker);
}
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_IMPL_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.h"
#include <utility>
#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/modules/cookie_store/cookie_store.h"
#include "third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h"
#include "third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.h"
namespace blink {
template <>
CookieStore* GlobalCookieStoreImpl<WorkerGlobalScope>::BuildCookieStore(
ExecutionContext* execution_context,
service_manager::InterfaceProvider* interface_provider) {
network::mojom::blink::RestrictedCookieManagerPtr cookie_manager_ptr;
interface_provider->GetInterface(mojo::MakeRequest(&cookie_manager_ptr));
blink::mojom::blink::CookieStorePtr cookie_store_ptr;
interface_provider->GetInterface(mojo::MakeRequest(&cookie_store_ptr));
return CookieStore::Create(execution_context, std::move(cookie_manager_ptr),
std::move(cookie_store_ptr));
}
CookieStore* ServiceWorkerGlobalScopeCookieStore::cookieStore(
ServiceWorkerGlobalScope& worker) {
// ServiceWorkerGlobalScope is Supplementable<WorkerGlobalScope>, not
// Supplementable<ServiceWorkerGlobalScope>.
return GlobalCookieStoreImpl<WorkerGlobalScope>::From(worker).GetCookieStore(
worker);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_SERVICE_WORKER_GLOBAL_SCOPE_COOKIE_STORE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_SERVICE_WORKER_GLOBAL_SCOPE_COOKIE_STORE_H_
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink {
class CookieStore;
class ServiceWorkerGlobalScope;
// Exposes a CookieStore as the "cookieStore" attribute on the SW global scope.
class ServiceWorkerGlobalScopeCookieStore {
STATIC_ONLY(ServiceWorkerGlobalScopeCookieStore);
public:
static CookieStore* cookieStore(ServiceWorkerGlobalScope&);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cookiechange);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_SERVICE_WORKER_GLOBAL_SCOPE_COOKIE_STORE_H_
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
[ [
RuntimeEnabled=AsyncCookies, RuntimeEnabled=AsyncCookies,
ImplementedAs=GlobalCookieStore ImplementedAs=ServiceWorkerGlobalScopeCookieStore
] partial interface ServiceWorkerGlobalScope { ] partial interface ServiceWorkerGlobalScope {
[Replaceable, SameObject] readonly attribute CookieStore cookieStore; [Replaceable, SameObject] readonly attribute CookieStore cookieStore;
attribute EventHandler oncookiechange;
}; };
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/cookie_store/window_cookie_store.h"
#include <utility>
#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/cookie_store/cookie_store.h"
#include "third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h"
namespace blink {
template <>
CookieStore* GlobalCookieStoreImpl<LocalDOMWindow>::BuildCookieStore(
ExecutionContext* execution_context,
service_manager::InterfaceProvider* interface_provider) {
network::mojom::blink::RestrictedCookieManagerPtr cookie_manager_ptr;
interface_provider->GetInterface(mojo::MakeRequest(&cookie_manager_ptr));
return CookieStore::Create(execution_context, std::move(cookie_manager_ptr),
blink::mojom::blink::CookieStorePtr());
}
CookieStore* WindowCookieStore::cookieStore(LocalDOMWindow& window) {
return GlobalCookieStoreImpl<LocalDOMWindow>::From(window).GetCookieStore(
window);
}
} // namespace blink
// Copyright 2017 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_WINDOW_COOKIE_STORE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_WINDOW_COOKIE_STORE_H_
#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator.h"
...@@ -11,19 +11,15 @@ namespace blink { ...@@ -11,19 +11,15 @@ namespace blink {
class CookieStore; class CookieStore;
class LocalDOMWindow; class LocalDOMWindow;
class ServiceWorkerGlobalScope;
// Exposes a CookieStore as the "cookieStore" attribute on the global scope. // Exposes a CookieStore as the "cookieStore" attribute on the Window global.
// class WindowCookieStore {
// This currently applies to Window scopes. STATIC_ONLY(WindowCookieStore);
class GlobalCookieStore {
STATIC_ONLY(GlobalCookieStore);
public: public:
static CookieStore* cookieStore(LocalDOMWindow&); static CookieStore* cookieStore(LocalDOMWindow&);
static CookieStore* cookieStore(ServiceWorkerGlobalScope&);
}; };
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_H_ #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_WINDOW_COOKIE_STORE_H_
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
[ [
RuntimeEnabled=AsyncCookies, RuntimeEnabled=AsyncCookies,
ImplementedAs=GlobalCookieStore, ImplementedAs=WindowCookieStore,
SecureContext SecureContext
] partial interface Window { ] partial interface Window {
[Replaceable, SameObject] readonly attribute CookieStore cookieStore; [Replaceable, SameObject] readonly attribute CookieStore cookieStore;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment