Skip to content
Permalink
Browse files
Add preliminary support for fetch event
https://bugs.webkit.org/show_bug.cgi?id=178171

Patch by Youenn Fablet <youenn@apple.com> on 2017-10-17
Reviewed by Chris Dumez.

Source/JavaScriptCore:

Adding events

* runtime/JSPromise.h:

Source/WebCore:

Test: http/wpt/service-workers/fetchEvent.https.html
      http/wpt/service-workers/extendableEvent.https.html

Adding support for ExtendableEvent and FetchEvent as per
https://w3c.github.io/ServiceWorker/v1/#extendableevent-interface and
https://w3c.github.io/ServiceWorker/v1/#fetchevent-interface.

Both events need to handle promises as method parameters.
Beefing up DOMPromise for that purpose by exposing status, result and being able to call then.
Adding a new DOMPromise create method that would be the base for https://heycam.github.io/webidl/#es-promise
which might be implemented in the binding generator as a follow-up.

This patch makes them exposed on Window for test purposes until they can be fully tested on ServiceWorker environment.
It is also adding two internal methods for the same reason. These should be removed once events can be tested in its environment.

* CMakeLists.txt:
* DerivedSources.make:
* Modules/fetch/FetchResponse.idl:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMPromise.cpp: Added.
(WebCore::callFunction):
(WebCore::DOMPromise::create):
(WebCore::DOMPromise::whenSettled):
(WebCore::DOMPromise::result const):
(WebCore::DOMPromise::status const):
* bindings/js/JSDOMPromise.h:
* bindings/js/WebCoreBuiltinNames.h:
* dom/EventNames.in:
* testing/Internals.cpp:
(WebCore::Internals::waitFetchEventToFinish):
(WebCore::Internals::waitExtendableEventToFinish):
* testing/Internals.h:
* testing/Internals.idl:
* workers/service/ExtendableEvent.cpp: Added.
(WebCore::ExtendableEvent::ExtendableEvent):
(WebCore::ExtendableEvent::waitUntil):
(WebCore::ExtendableEvent::addPendingPromise):
* workers/service/ExtendableEvent.h:
(WebCore::ExtendableEvent::onFinishedWaiting):
(WebCore::ExtendableEvent::promiseSettled):
* workers/service/ExtendableEvent.idl: Added.
* workers/service/ExtendableEventInit.h: Added.
* workers/service/ExtendableEventInit.idl: Added.
* workers/service/FetchEvent.cpp: Added.
(WebCore::FetchEvent::FetchEvent):
(WebCore::FetchEvent::respondWith):
(WebCore::FetchEvent::onResponse):
(WebCore::FetchEvent::respondWithError):
(WebCore::FetchEvent::processResponse):
(WebCore::FetchEvent::promiseSettled):
* workers/service/FetchEvent.h:
* workers/service/FetchEvent.idl:

LayoutTests:

Skipping new tests for WK1 and GTK that do not have SW.

* http/wpt/service-workers/extendableEvent.https-expected.txt: Added.
* http/wpt/service-workers/extendableEvent.https.html: Added.
* http/wpt/service-workers/fetchEvent.https-expected.txt: Added.
* http/wpt/service-workers/fetchEvent.https.html: Added.
* platform/gtk/TestExpectations:
* platform/ios-wk1/TestExpectations:
* platform/mac-wk1/TestExpectations:

Canonical link: https://commits.webkit.org/194624@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223562 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
youennf authored and webkit-commit-queue committed Oct 17, 2017
1 parent f001cd6 commit 756621082cc74fac35021b4b2380a73319919051
Showing with 1,089 additions and 3 deletions.
  1. +17 −0 LayoutTests/ChangeLog
  2. +22 −0 LayoutTests/http/wpt/resources/gc.js
  3. +6 −0 LayoutTests/http/wpt/service-workers/extendableEvent.https-expected.txt
  4. +63 −0 LayoutTests/http/wpt/service-workers/extendableEvent.https.html
  5. +10 −0 LayoutTests/http/wpt/service-workers/fetchEvent.https-expected.txt
  6. +107 −0 LayoutTests/http/wpt/service-workers/fetchEvent.https.html
  7. +1 −0 LayoutTests/platform/ios-wk1/TestExpectations
  8. +1 −0 LayoutTests/platform/mac-wk1/TestExpectations
  9. +11 −0 Source/JavaScriptCore/ChangeLog
  10. +1 −1 Source/JavaScriptCore/runtime/JSPromise.h
  11. +6 −0 Source/WebCore/CMakeLists.txt
  12. +60 −0 Source/WebCore/ChangeLog
  13. +3 −0 Source/WebCore/DerivedSources.make
  14. +1 −0 Source/WebCore/Modules/fetch/FetchRequest.idl
  15. +1 −1 Source/WebCore/Modules/fetch/FetchResponse.idl
  16. +48 −0 Source/WebCore/WebCore.xcodeproj/project.pbxproj
  17. +109 −0 Source/WebCore/bindings/js/JSDOMPromise.cpp
  18. +7 −0 Source/WebCore/bindings/js/JSDOMPromise.h
  19. +36 −0 Source/WebCore/bindings/js/JSFetchEventCustom.cpp
  20. +2 −0 Source/WebCore/bindings/js/WebCoreBuiltinNames.h
  21. +2 −0 Source/WebCore/dom/EventNames.in
  22. +27 −1 Source/WebCore/testing/Internals.cpp
  23. +8 −0 Source/WebCore/testing/Internals.h
  24. +4 −0 Source/WebCore/testing/Internals.idl
  25. +78 −0 Source/WebCore/workers/service/ExtendableEvent.cpp
  26. +65 −0 Source/WebCore/workers/service/ExtendableEvent.h
  27. +38 −0 Source/WebCore/workers/service/ExtendableEvent.idl
  28. +39 −0 Source/WebCore/workers/service/ExtendableEventInit.h
  29. +30 −0 Source/WebCore/workers/service/ExtendableEventInit.idl
  30. +148 −0 Source/WebCore/workers/service/FetchEvent.cpp
  31. +87 −0 Source/WebCore/workers/service/FetchEvent.h
  32. +51 −0 Source/WebCore/workers/service/FetchEvent.idl
@@ -1,3 +1,20 @@
2017-10-17 Youenn Fablet <youenn@apple.com>

Add preliminary support for fetch event
https://bugs.webkit.org/show_bug.cgi?id=178171

Reviewed by Chris Dumez.

Skipping new tests for WK1 and GTK that do not have SW.

* http/wpt/service-workers/extendableEvent.https-expected.txt: Added.
* http/wpt/service-workers/extendableEvent.https.html: Added.
* http/wpt/service-workers/fetchEvent.https-expected.txt: Added.
* http/wpt/service-workers/fetchEvent.https.html: Added.
* platform/gtk/TestExpectations:
* platform/ios-wk1/TestExpectations:
* platform/mac-wk1/TestExpectations:

2017-10-17 Youenn Fablet <youenn@apple.com>

Cache API implementation should be able to compute storage size for WebKit client applications.
@@ -0,0 +1,22 @@
// If there is no window.gc() already defined, define one using the best
// method we can find.
// The slow fallback should not hit in the actual test environment.
if (!window.gc)
{
window.gc = function()
{
if (window.GCController)
return GCController.collect();

console.warn('Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.');
function gcRec(n) {
if (n < 1)
return {};
var temp = {i: "ab" + i + (i / 100000)};
temp += "foo";
gcRec(n-1);
}
for (var i = 0; i < 10000; i++)
gcRec(10);
}
}
@@ -0,0 +1,6 @@

PASS ExtendableEvent waitUntil should support non promise parameters
PASS ExtendableEvent should wait for given promise to resolve
PASS ExtendableEvent should wait for given promise to reject
PASS Event constructors

@@ -0,0 +1,63 @@
<!DOCTYPE html>
<title>Service Worker Extendable Event</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// FIXME: Should be run on a service worker.
test(() => {
if (!window.internals)
return Promise.reject("test require internals");
var event = new ExtendableEvent('ExtendableEvent', {});
assert_throws('InvalidStateError', () => event.waitUntil(new Request('')));
}, "ExtendableEvent waitUntil should support non promise parameters");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = internals.createTrustedExtendableEvent();
var promise = internals.waitForExtendableEventToFinish(event);
var shouldWait = true;
event.waitUntil(new Promise((resolve, reject) => {
setTimeout(() => {
shouldWait = false;
resolve(new Request(''));
}, 50);
}));
await promise;
assert_false(shouldWait);
}, "ExtendableEvent should wait for given promise to resolve");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = internals.createTrustedExtendableEvent();
var promise = internals.waitForExtendableEventToFinish(event);
var shouldWait = true;
event.waitUntil(new Promise((resolve, reject) => {
setTimeout(() => {
shouldWait = false;
reject(new Request(''));
}, 50);
}));
await promise;
assert_false(shouldWait);
}, "ExtendableEvent should wait for given promise to reject");

test(function() {
assert_equals(
new ExtendableEvent('ExtendableEvent').type,
'ExtendableEvent', 'Type of ExtendableEvent should be ExtendableEvent');
assert_equals(
new ExtendableEvent('ExtendableEvent', {}).type,
'ExtendableEvent', 'Type of ExtendableEvent should be ExtendableEvent');
assert_equals(
new ExtendableEvent('ExtendableEvent', {}).cancelable,
false, 'Default ExtendableEvent.cancelable should be false');
assert_equals(
new ExtendableEvent('ExtendableEvent', {}).bubbles,
false, 'Default ExtendableEvent.bubbles should be false');
assert_equals(
new ExtendableEvent('ExtendableEvent', {cancelable: false}).cancelable,
false, 'ExtendableEvent.cancelable should be false');
}, 'Event constructors');
</script>
@@ -0,0 +1,10 @@

PASS FetchEvent respondWith should throw if called twice
PASS FetchEvent request is SameObject
PASS FetchEvent should be in error if responding with undefined
PASS FetchEvent should be in error if not responding with a Response
PASS FetchEvent should be in error if responding with a Promise that does not resolve to a Response
PASS FetchEvent should be in error if responding with a Promise that rejects
PASS FetchEvent should resolve when responding with a Response
PASS Event constructors

@@ -0,0 +1,107 @@
<!DOCTYPE html>
<title>Service Worker Fetch Event</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/WebKit/resources/gc.js"></script>
<script>
// FIXME: Should be run on a service worker.
test(() => {
var event = new FetchEvent('FetchEvent', { request : new Request('') });
event.respondWith(undefined);
assert_throws('InvalidStateError', () => event.respondWith(undefined));
}, "FetchEvent respondWith should throw if called twice");

test(() => {
var event = new FetchEvent('FetchEvent', { request : new Request('test') });
event.request.value = 1;
gc();
assert_equals(event.request.value, 1);
}, "FetchEvent request is SameObject");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = new FetchEvent('FetchEvent', { request : new Request('') });
var promise = internals.waitForFetchEventToFinish(event);
event.respondWith(undefined);
return promise_rejects(t, new TypeError, promise);
}, "FetchEvent should be in error if responding with undefined");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = new FetchEvent('FetchEvent', { request : new Request('') });
var promise = internals.waitForFetchEventToFinish(event);
event.respondWith(new Request(''));
return promise_rejects(t, new TypeError, promise);
}, "FetchEvent should be in error if not responding with a Response");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = new FetchEvent('FetchEvent', { request : new Request('') });
var promise = internals.waitForFetchEventToFinish(event);
event.respondWith(new Promise((resolve, reject) => {
resolve(new Request(''));
}));
return promise_rejects(t, new TypeError, promise);
}, "FetchEvent should be in error if responding with a Promise that does not resolve to a Response");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = new FetchEvent('FetchEvent', { request : new Request('') });
var promise = internals.waitForFetchEventToFinish(event);
event.respondWith(new Promise((resolve, reject) => {
reject('not good');
}));
return promise_rejects(t, new TypeError, promise);
}, "FetchEvent should be in error if responding with a Promise that rejects");

promise_test(async t => {
if (!window.internals)
return Promise.reject("test require internals");
var event = new FetchEvent('FetchEvent', { request : new Request('') });
var response = new Response;
event.respondWith(response);
assert_true(response === await internals.waitForFetchEventToFinish(event));
}, "FetchEvent should resolve when responding with a Response");

// Duplicate test from WPT. To be removed once WPT service worker tests are active.
test(function() {
var req = new Request('http://localhost:8800/',
{method: 'POST',
headers: [['Content-Type', 'Text/Html']]});
assert_equals(
new ExtendableEvent('ExtendableEvent').type,
'ExtendableEvent', 'Type of ExtendableEvent should be ExtendableEvent');
assert_throws(new TypeError, function() {
new FetchEvent('FetchEvent');
}, 'FetchEvent constructor with one argument throws');
assert_throws(new TypeError, function() {
new FetchEvent('FetchEvent', {});
}, 'FetchEvent constructor with empty init dict throws');
assert_throws(new TypeError, function() {
new FetchEvent('FetchEvent', {request: null});
}, 'FetchEvent constructor with null request member throws');
assert_equals(
new FetchEvent('FetchEvent', {request: req}).type,
'FetchEvent', 'Type of FetchEvent should be FetchEvent');
assert_equals(
new FetchEvent('FetchEvent', {request: req}).cancelable,
false, 'Default FetchEvent.cancelable should be false');
assert_equals(
new FetchEvent('FetchEvent', {request: req}).bubbles,
false, 'Default FetchEvent.bubbles should be false');
assert_equals(
new FetchEvent('FetchEvent', {request: req, cancelable: false}).cancelable,
false, 'FetchEvent.cancelable should be false');
assert_equals(
new FetchEvent('FetchEvent', {request: req, clientId : 'test-client-id'}).clientId, 'test-client-id',
'FetchEvent.clientId with option {clientId : "test-client-id"} should be "test-client-id"');
assert_equals(
new FetchEvent('FetchEvent', {request : req, isReload : true}).request.url,
'http://localhost:8800/',
'FetchEvent.request.url should return the value it was initialized to');
}, 'Event constructors');
</script>
@@ -9,6 +9,7 @@ editing/input/focus-change-with-marked-text.html [ Pass ]

# No service worker implementation for WK1
imported/w3c/web-platform-tests/service-workers [ Skip ]
http/wpt/service-workers [ Skip ]
http/wpt/cache-storage [ Skip ]
http/tests/cache-storage [ Skip ]

@@ -104,6 +104,7 @@ http/tests/ssl/media-stream

# No service worker implementation for WK1
imported/w3c/web-platform-tests/service-workers [ Skip ]
http/wpt/service-workers [ Skip ]
http/wpt/cache-storage [ Skip ]
http/tests/cache-storage [ Skip ]

@@ -1,3 +1,14 @@
2017-10-17 Youenn Fablet <youenn@apple.com>

Add preliminary support for fetch event
https://bugs.webkit.org/show_bug.cgi?id=178171

Reviewed by Chris Dumez.

Adding events

* runtime/JSPromise.h:

2017-10-10 Yusuke Suzuki <utatane.tea@gmail.com>

[JSC] __proto__ getter should be fast
@@ -44,7 +44,7 @@ class JSPromise : public JSNonFinalObject {
Rejected
};

Status status(VM&) const;
JS_EXPORT_PRIVATE Status status(VM&) const;
JS_EXPORT_PRIVATE JSValue result(VM&) const;
JS_EXPORT_PRIVATE bool isHandled(VM&) const;

@@ -786,6 +786,9 @@ set(WebCore_NON_SVG_IDL_FILES
workers/WorkerLocation.idl
workers/WorkerType.idl

workers/service/ExtendableEvent.idl
workers/service/ExtendableEventInit.idl
workers/service/FetchEvent.idl
workers/service/ServiceWorker.idl
workers/service/ServiceWorkerContainer.idl
workers/service/ServiceWorkerGlobalScope.idl
@@ -1287,6 +1290,7 @@ set(WebCore_SOURCES
bindings/js/JSDOMGlobalObjectTask.cpp
bindings/js/JSDOMGuardedObject.cpp
bindings/js/JSDOMMapLike.cpp
bindings/js/JSDOMPromise.cpp
bindings/js/JSDOMPromiseDeferred.cpp
bindings/js/JSDOMWindowBase.cpp
bindings/js/JSDOMWindowCustom.cpp
@@ -3075,6 +3079,8 @@ set(WebCore_SOURCES
workers/WorkerScriptLoader.cpp
workers/WorkerThread.cpp

workers/service/ExtendableEvent.cpp
workers/service/FetchEvent.cpp
workers/service/ServiceWorker.cpp
workers/service/ServiceWorkerContainer.cpp
workers/service/ServiceWorkerGlobalScope.cpp
@@ -1,3 +1,63 @@
2017-10-17 Youenn Fablet <youenn@apple.com>

Add preliminary support for fetch event
https://bugs.webkit.org/show_bug.cgi?id=178171

Reviewed by Chris Dumez.

Test: http/wpt/service-workers/fetchEvent.https.html
http/wpt/service-workers/extendableEvent.https.html

Adding support for ExtendableEvent and FetchEvent as per
https://w3c.github.io/ServiceWorker/v1/#extendableevent-interface and
https://w3c.github.io/ServiceWorker/v1/#fetchevent-interface.

Both events need to handle promises as method parameters.
Beefing up DOMPromise for that purpose by exposing status, result and being able to call then.
Adding a new DOMPromise create method that would be the base for https://heycam.github.io/webidl/#es-promise
which might be implemented in the binding generator as a follow-up.

This patch makes them exposed on Window for test purposes until they can be fully tested on ServiceWorker environment.
It is also adding two internal methods for the same reason. These should be removed once events can be tested in its environment.

* CMakeLists.txt:
* DerivedSources.make:
* Modules/fetch/FetchResponse.idl:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMPromise.cpp: Added.
(WebCore::callFunction):
(WebCore::DOMPromise::create):
(WebCore::DOMPromise::whenSettled):
(WebCore::DOMPromise::result const):
(WebCore::DOMPromise::status const):
* bindings/js/JSDOMPromise.h:
* bindings/js/WebCoreBuiltinNames.h:
* dom/EventNames.in:
* testing/Internals.cpp:
(WebCore::Internals::waitFetchEventToFinish):
(WebCore::Internals::waitExtendableEventToFinish):
* testing/Internals.h:
* testing/Internals.idl:
* workers/service/ExtendableEvent.cpp: Added.
(WebCore::ExtendableEvent::ExtendableEvent):
(WebCore::ExtendableEvent::waitUntil):
(WebCore::ExtendableEvent::addPendingPromise):
* workers/service/ExtendableEvent.h:
(WebCore::ExtendableEvent::onFinishedWaiting):
(WebCore::ExtendableEvent::promiseSettled):
* workers/service/ExtendableEvent.idl: Added.
* workers/service/ExtendableEventInit.h: Added.
* workers/service/ExtendableEventInit.idl: Added.
* workers/service/FetchEvent.cpp: Added.
(WebCore::FetchEvent::FetchEvent):
(WebCore::FetchEvent::respondWith):
(WebCore::FetchEvent::onResponse):
(WebCore::FetchEvent::respondWithError):
(WebCore::FetchEvent::processResponse):
(WebCore::FetchEvent::promiseSettled):
* workers/service/FetchEvent.h:
* workers/service/FetchEvent.idl:

2017-10-17 Jer Noble <jer.noble@apple.com>

Leak of one AVSampleCursor inside ImageDecoderAVFObjC::createFrameImageAtIndex()
@@ -910,6 +910,9 @@ JS_BINDING_IDLS = \
$(WebCore)/workers/WorkerGlobalScope.idl \
$(WebCore)/workers/WorkerLocation.idl \
$(WebCore)/workers/WorkerType.idl \
$(WebCore)/workers/service/ExtendableEvent.idl \
$(WebCore)/workers/service/ExtendableEventInit.idl \
$(WebCore)/workers/service/FetchEvent.idl \
$(WebCore)/workers/service/ServiceWorker.idl \
$(WebCore)/workers/service/ServiceWorkerContainer.idl \
$(WebCore)/workers/service/ServiceWorkerGlobalScope.idl \
@@ -39,6 +39,7 @@ typedef (Blob or BufferSource or DOMFormData or URLSearchParams or ReadableStrea
ConstructorCallWith=ScriptExecutionContext,
EnabledAtRuntime=FetchAPI,
Exposed=(Window,Worker),
GenerateIsReachable=Impl,
InterfaceName=Request,
] interface FetchRequest {
readonly attribute ByteString method;
@@ -43,7 +43,7 @@ dictionary FetchResponseInit {
ConstructorCallWith=ScriptExecutionContext,
ConstructorMayThrowException,
EnabledAtRuntime=FetchAPI,
ExportToWrappedFunction,
ExportMacro=WEBCORE_EXPORT,
Exposed=(Window,Worker),
InterfaceName=Response,
] interface FetchResponse {

0 comments on commit 7566210

Please sign in to comment.