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 => {
assert_true(event instanceof ExtendableCookieChangeEvent);
assert_true(event instanceof ExtendableEvent);
await async_cleanup(() => {
cookieStore.delete('cookie-name');
await async_cleanup(async () => {
await cookieStore.delete('cookie-name');
g_cookie_changes = [];
RearmCookieChangeReceivedPromise();
});
......
......@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => {
event.waitUntil((async () => {
cookieStore.subscribeToChanges([
await cookieStore.subscribeToChanges([
{ name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]);
})());
});
......@@ -57,7 +57,8 @@ promise_test(async testCase => {
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');
await async_cleanup(() => cookieStore.delete('cookie-name'));
}, 'cookiechange dispatched with cookie change that matches subscription ' +
'to event handler registered with addEventListener');
done();
......@@ -6,7 +6,7 @@ importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => {
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");
self.addEventListener('install', (event) => {
event.waitUntil((async () => {
cookieStore.subscribeToChanges([
await cookieStore.subscribeToChanges([
{ name: 'cookie-name', matchType: 'equals', url: '/scope/path' }]);
})());
});
......@@ -44,9 +44,9 @@ promise_test(async testCase => {
assert_equals(event.changed[0].name, 'cookie-name');
assert_equals(event.changed[0].value, 'cookie-value');
await async_cleanup(() => {
cookieStore.delete('another-cookie-name');
cookieStore.delete('cookie-name');
await async_cleanup(async () => {
await cookieStore.delete('another-cookie-name');
await cookieStore.delete('cookie-name');
});
}, 'cookiechange not dispatched for change that does not match subscription');
......
......@@ -108,4 +108,5 @@ partial interface Window {
partial interface ServiceWorkerGlobalScope {
[Replaceable, SameObject] readonly attribute CookieStore cookieStore;
attribute EventHandler oncookiechange;
};
......@@ -2623,6 +2623,7 @@ interface WritableStream
getter onbackgroundfetched
getter onbackgroundfetchfail
getter oncanmakepayment
getter oncookiechange
getter onfetch
getter oninstall
getter onmessage
......@@ -2643,6 +2644,7 @@ interface WritableStream
setter onbackgroundfetched
setter onbackgroundfetchfail
setter oncanmakepayment
setter oncookiechange
setter onfetch
setter oninstall
setter onmessage
......
......@@ -12,8 +12,11 @@ blink_modules_sources("cookie_store") {
"cookie_store.h",
"extendable_cookie_change_event.cc",
"extendable_cookie_change_event.h",
"global_cookie_store.cc",
"global_cookie_store.h",
"global_cookie_store_impl.h",
"service_worker_global_scope_cookie_store.cc",
"service_worker_global_scope_cookie_store.h",
"window_cookie_store.cc",
"window_cookie_store.h",
]
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
// 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 "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/core/workers/worker_thread.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/supplementable.h"
namespace blink {
namespace {
template <typename T>
class GlobalCookieStoreImpl final
: public GarbageCollected<GlobalCookieStoreImpl<T>>,
......@@ -67,48 +61,11 @@ class GlobalCookieStoreImpl final
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
template <typename T>
const char GlobalCookieStoreImpl<T>::kSupplementName[] =
"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
#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 @@
[
RuntimeEnabled=AsyncCookies,
ImplementedAs=GlobalCookieStore
ImplementedAs=ServiceWorkerGlobalScopeCookieStore
] partial interface ServiceWorkerGlobalScope {
[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
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_GLOBAL_COOKIE_STORE_H_
#define 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_WINDOW_COOKIE_STORE_H_
#include "third_party/blink/renderer/platform/wtf/allocator.h"
......@@ -11,19 +11,15 @@ namespace blink {
class CookieStore;
class LocalDOMWindow;
class ServiceWorkerGlobalScope;
// Exposes a CookieStore as the "cookieStore" attribute on the global scope.
//
// This currently applies to Window scopes.
class GlobalCookieStore {
STATIC_ONLY(GlobalCookieStore);
// Exposes a CookieStore as the "cookieStore" attribute on the Window global.
class WindowCookieStore {
STATIC_ONLY(WindowCookieStore);
public:
static CookieStore* cookieStore(LocalDOMWindow&);
static CookieStore* cookieStore(ServiceWorkerGlobalScope&);
};
} // 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 @@
[
RuntimeEnabled=AsyncCookies,
ImplementedAs=GlobalCookieStore,
ImplementedAs=WindowCookieStore,
SecureContext
] partial interface Window {
[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