Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async waitUntil microtask issue #1213

Closed
wanderview opened this issue Oct 20, 2017 · 35 comments
Closed

async waitUntil microtask issue #1213

wanderview opened this issue Oct 20, 2017 · 35 comments

Comments

@wanderview
Copy link
Member

As you may be aware the firefox Promise implementation has not been using proper microtasks and we're trying to fix that. Part of that effort uncovered an issue with a test for async waitUntil():

https://bugzilla.mozilla.org/show_bug.cgi?id=1409979

Apparently the spec is correct, but the test follows an incorrect interpretation based on our bogus microstask handling. Chrome matched the test expectation by doing this workaround:

https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.cpp?l=145&rcl=c2665c0a9bfec6379c90d3ea36199ee6a3e9f024

We would like to correct the test to follow the spec and real microtask definition, but wanted to make sure everyone was ok with that since chrome matches behavior.

We think this example from the original issue is incorrect: #1039 (comment)

And this WPT test condition should return OK and not throw an InvalidStateError:

https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L20

@mfalken
Copy link
Member

mfalken commented Oct 20, 2017

I'm OK with changing the test as I suspect you're right about the spec. Just not sure why we got it wrong in the first place. Did we all just read the spec wrong when discussing #1039 ? It's very hard for me to read the Service Worker spec and DOM spec and piece together what the expected behavior is.. easier to understand via WPT tests and examples.

@aliams
Copy link
Contributor

aliams commented Oct 20, 2017

I also agree with changing the test. Thanks for spotting this @wanderview!

@wanderview
Copy link
Member Author

Actually, now I'm confused again. I would think step 5 here would mean we throw since we should queue the microtask to decrement the number of pending promises:

https://w3c.github.io/ServiceWorker/#wait-until-method

@wanderview
Copy link
Member Author

Olli suggests that the test should be saying "OK" there because the dispatch flag is set, I think:

https://bugzilla.mozilla.org/show_bug.cgi?id=1409979#c4

Because we are running the test from an event handler.

Would we throw InvalidStateError if we tried to do it from a setTimeout()?

I'm not sure I understand why the dispatch flag matters here.

@smaug----
Copy link

Yes, setTimeout creates its own task, so the event isn't being dispatched during that time.

@wanderview
Copy link
Member Author

I think the intent of checking the dispatch flag is to allow the initial waitUntil() to be called on first dispatch of the functional event.

@wanderview
Copy link
Member Author

I guess the setTimeout() case is already tested here:

https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L17

So I guess we can just mark this test case as returning OK:

https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L20

Maybe with a comment that its ok since the dispatching flag is set.

If we really wanted to we could add a 3rd test case that adds a setTimeout() before the async_microtask_waituntil to show that it should fail if the dispatch flag is not set.

@mfalken
Copy link
Member

mfalken commented Oct 20, 2017

Just a question: is the dispatch flag set whenever you are in a microtask "chained" to the original event dispatch? e.g., does this throw?

onfetch = e => {
  Promise.resolve().then(_ => Promise.resolve()).then(_ => Promise.resolve()).then(_ => e.waitUntil(p));
};

Similarly how about this one:

onfetch = e => {
  e.waitUntil(some_promise);
  some_promise.then(_ => Promise.resolve()).then(_ => Promise.resolve()).then(_ => e.waitUntil(another_promise));
};

@smaug----
Copy link

If more microtask stuff is added during a microtask checkpoint, they all are handled during that checkpoint. Microtasks are synchronous from browser point of view.
See the while loop in https://html.spec.whatwg.org/#perform-a-microtask-checkpoint

@jungkees
Copy link
Collaborator

So I guess we can just mark this test case as returning OK:

https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L20

I think the current test is what we settled on. I.e., it should throw in that case.

We think this example from the original issue is incorrect: #1039 (comment)

I think #1039 (comment) is the expected behavior we agreed. That is, we wanted to disallow a further lifetime extension in any async task when there's no holding extension promise.

Olli suggests that the test should be saying "OK" there because the dispatch flag is set, I think:

I don't think the dispatch flag is set when the waitUntil is called in the microtask. The microtask checkpoint is performed after the event-dispatcher task is finished.

@smaug----
Copy link

The microtask checkpoint is performed after the event-dispatcher task is finished.

No it isn't, except if there is some other JS on stack too (like, if the event is dispatched from JS).
Microtask checkpoint happens at the end of the outermost script execution and at the end of a task
(+ couple of special cases, like right before <script> execution)

@jungkees
Copy link
Collaborator

I thought if dispatch is invoked in a task, any microtasks queued in the task wouldn't be scheduled until the dispatch steps run to completion. Am I understanding it incorrectly?

@smaug----
Copy link

If there isn't any other script on stack, microtask checkpoint happens at the end of the each event listener call. So, if there are several listeners for an event, there will be several microtask checkpoints per event dispatch.

@jungkees
Copy link
Collaborator

I think those microtask checkpoints are preceded by the completion of the dispatch algorithm (where the dispatch flag's unset) regardless how many other tasks would be queued in the interim.

@bevis-tseng
Copy link

bevis-tseng commented Oct 24, 2017

No, the dispatch flag is unset after microtask checkpoints of event listeners are performed, according to https://dom.spec.whatwg.org/#dispatching-events:

  1. the dispatch flag is set at step 1 and is unset and step 14.
  2. the listener callbacks could be invoked in step 12.4 and step 13.6.
  3. in https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke, each callback invocation (step 16.2 of [1]) contains a microtask checkpoint specified in [2].
    [1] https://heycam.github.io/webidl/#call-a-user-objects-operation
    [2] https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

@jungkees
Copy link
Collaborator

  1. in https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke, each callback invocation (step 16.2 of [1]) contains a microtask checkpoint specified in [2].

I didn't realize the execution of each listener callback consumes the microtasks. That considered, I agree the WPT test (calling waitUntil() in a microtask) returns OK and doesn't throw an InvalidStateError. Thanks for the pointers. Sorry for my confusion.

@jungkees
Copy link
Collaborator

Reviewing the other cases again, I'm confused about the current-extension-expired-same-microtask-turn-extra case. Shouldn't it return OK because all the microtasks in the example will be consumed before the dispatch flag is unset?

@wanderview
Copy link
Member Author

wanderview commented Oct 27, 2017

Reviewing the other cases again, I'm confused about the current-extension-expired-same-microtask-turn-extra case. Shouldn't it return OK because all the microtasks in the example will be consumed before the dispatch flag is unset?

Per the spec language I think you are right.

Looking at why our implementationdoesn't do that, we end up removing the "keep alive token" via a microtask:

https://searchfox.org/mozilla-central/source/dom/workers/ServiceWorkerPrivate.cpp#386
https://searchfox.org/mozilla-central/source/dom/workers/ServiceWorkerPrivate.cpp#356

This then means when the next WaitUntil() is called in a later microtask in the same dispatching task the "keep alive token" is gone.

I was thinking maybe we could make it respect the dispatch flag here, but the "keep alive token" is created on another thread. It would be very difficult to do this in firefox.

What would people think about adding another flag that says "extension promises were added and now all consumed"? If that flag is set, then we don't allow new extension promises to be added even if we are still dispatching the event. This might meet our original intent here?

@jakearchibald
Copy link
Contributor

I think our spec wording is a little wrong here.

Upon fulfillment or rejection of f, queue a microtask to run these substeps:

Fulfillment already queues a microtask, so we may be doing something redundant. Unless we're intentionally adding a microtask to a microtask, which I don't think we are.

I'm struggling to get my head around this. I don't think this should work:

const p = doSomething();
event.waitUntil(p);
p.then(() => event.waitUntil(doSomethingElse()));

Because the pending promises count will be 0 when event.waitUntil is called. This is because the spec's microtask is in the queue before the p.then handler. Whereas:

const p = doSomething();
p.then(() => event.waitUntil(doSomethingElse()));
event.waitUntil(p);

…would work, since the p.then handler is in the queue before the spec's microtask.

I guess it's a bit of a gotcha, but it'll fail consistently.

@jakearchibald
Copy link
Contributor

jakearchibald commented Nov 7, 2017

F2F: My comment above is wrong. The double microtask is intentional. The use of the dispatch flag is intentional and catches an edge case with multiple event listeners:

addEventListener('fetch', event => {
  event.waitUntil(Promise.resolve());
});

addEventListener('fetch', event => {
  // This should work, and it's the dispatch flag that makes it work.
  event.waitUntil(whatever());
});

Action: Review the tests for this.

https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L20 - waitUntil shouldn't throw here.

@jungkees
Copy link
Collaborator

Thanks for clarifying with the tests, @aliams. I think we mostly agree on the current spec behavior for waitUntil(), but would like to clarify some points:

I was thinking maybe we could make it respect the dispatch flag here, but the "keep alive token" is created on another thread. It would be very difficult to do this in firefox.

@wanderview, do you still have this issue or is it implementable? I thought of using event's extend lifetime promises for checking "extension promises were added" condition in your comment, but we still don't solve #1213 (comment) case without the dispatch flag.

Having thought on it, (throwing when the dispatch flag is unset && count == 0) explains the desired behavior well I think. That is, the event is basically extendable during its own task turn and during when the extension opportunity isn't closed.

Other than that, I'm a bit uncomfortable with the following cases. What do you think about them?

const p = async_task_waituntil();
event.waitUntil(p);
p.then(() => { Promise.resolve().then(() => event.waitUntil(q)) }); // Throw.

This throws since the count decrement microtask queued by waitUntil step 5 will run before the microtask queued by p.then callback.

const p = async_task_waituntil();
p.then(() => { Promise.resolve().then(() => event.waitUntil(q)) }); // OK.
event.waitUntil(p);

This runs OK since the count decrement microtask queued by waitUntil step 5 will run after the microtask queued by p.then callback.

@aliams
Copy link
Contributor

aliams commented Jan 19, 2018

Is that to say that the test calling waitUntil in a different microtask without an existing extension should still throw. And that the test calling waitUntil at the end of the microtask turn still throws too? I believe due to the dispatch flag, these should actually be succeeding.

@aliams
Copy link
Contributor

aliams commented Jan 19, 2018

@jungkees, are these what the tests would look like for what you are describing in your examples?

  1.  waitPromise = async_task_waituntil(event);
     event.waitUntil(waitPromise);
     waitPromise.then(() => {
         return Promise.resolve().then(() => sync_waituntil(event))
     }).then(reportResultExpecting('InvalidStateError'));
  2.  waitPromise = async_task_waituntil(event);
     waitPromise.then(() => {
         return Promise.resolve().then(() => sync_waituntil(event))
     }).then(reportResultExpecting('OK'));
     event.waitUntil(waitPromise);

@jungkees
Copy link
Collaborator

@aliams, yes, the tests look equivalent to the examples I gave above. I was talking about the cases where the promise (waitPromise in your example) resolves in an async task. The result of the waitUtil called in the extra microtask turn depends on whether the microtask for decrementing the pending lifetime promise count was called or not. The question was whether this would be expected behaviors?

@mfalken
Copy link
Member

mfalken commented Mar 15, 2019

Sorry no that can't be right. p could take a long time and it doesn't make sense for the event dispatch flag to still be set in that case. I wonder if it matters that the test is using p = Promise.resolve() instead of a longer promise like one that resolves after setTimeout.

@mfalken
Copy link
Member

mfalken commented Mar 15, 2019

To anyone interested, I have a patch with proposed test changes in https://chromium-review.googlesource.com/c/chromium/src/+/1524393.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 15, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because when respondWith() is called the
event dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 15, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because when respondWith() is called the
event dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
@wanderview
Copy link
Member Author

Sorry no that can't be right. p could take a long time and it doesn't make sense for the event dispatch flag to still be set in that case. I wonder if it matters that the test is using p = Promise.resolve() instead of a longer promise like one that resolves after setTimeout.

FWIW, I think this analysis here is correct and your test looks good. Thanks!

@annevk
Copy link
Member

annevk commented Mar 15, 2019

I wonder if it matters

As far as I know you cannot trigger this situation in other ways (except via similar promise APIs that have near-identical semantics, if those exist). Certainly not with setTimeout.

@wanderview
Copy link
Member Author

I think in theory something like a fetch() to a data URL could resolve in a single microtask like Promise.resolve(). It wouldn't be guaranteed, though, of course.

@asutherland
Copy link

Thanks for the clarification and the test changes! I think the initially referenced Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=1409979 and the failures in that WPT PR for Firefox are now just about Firefox's ExtendableEvent.waitUntil() failing to check the dispatch flag.

@annevk
Copy link
Member

annevk commented Mar 16, 2019

@wanderview no, that should at the very least queue a task from the fetch layer.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 18, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because when respondWith() is called while the
event dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 18, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because when respondWith() is called while the
event dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 18, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 18, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 18, 2019
See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
foolip pushed a commit to web-platform-tests/wpt that referenced this issue Mar 18, 2019
…15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
@mfalken
Copy link
Member

mfalken commented Mar 19, 2019

Thanks all! the WPT tests have been updated. The tricky part was indeed that some tests were using Promise.resolve() which meant the event dispatch flag was still set when the test intended to test the pending promises count instead. I've added test cases for those now.

I think we can now close this.

@mfalken mfalken closed this as completed Mar 19, 2019
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Apr 23, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Apr 24, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852
mykmelez pushed a commit to mykmelez/gecko that referenced this issue Apr 25, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852
mykmelez pushed a commit to mykmelez/gecko that referenced this issue Apr 25, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852
marcoscaceres pushed a commit to web-platform-tests/wpt that referenced this issue Jul 23, 2019
…15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641514}
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Oct 4, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falkenchromium.org>
Reviewed-by: Ben Kelly <wanderviewchromium.org>
Cr-Commit-Position: refs/heads/master{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852

UltraBlame original commit: a941738d800eb075978e20b17f3a72cb680a8398
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Oct 4, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falkenchromium.org>
Reviewed-by: Ben Kelly <wanderviewchromium.org>
Cr-Commit-Position: refs/heads/master{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852

UltraBlame original commit: b4b704c52ae96a9cdfbc3c4565a39d17f2480d19
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Oct 4, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falkenchromium.org>
Reviewed-by: Ben Kelly <wanderviewchromium.org>
Cr-Commit-Position: refs/heads/master{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852

UltraBlame original commit: a941738d800eb075978e20b17f3a72cb680a8398
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Oct 4, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falkenchromium.org>
Reviewed-by: Ben Kelly <wanderviewchromium.org>
Cr-Commit-Position: refs/heads/master{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852

UltraBlame original commit: b4b704c52ae96a9cdfbc3c4565a39d17f2480d19
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Oct 4, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falkenchromium.org>
Reviewed-by: Ben Kelly <wanderviewchromium.org>
Cr-Commit-Position: refs/heads/master{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852

UltraBlame original commit: a941738d800eb075978e20b17f3a72cb680a8398
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Oct 4, 2019
…ync respondWith/waitUntil., a=testonly

Automatic update from web-platform-tests
service worker: Improve WPT tests for async respondWith/waitUntil. (#15852)

See discussion at [1] and [2].

This makes the following changes.

1.
Adds a test for:

self.addEventListener('fetch', e => {
  Promise.resolve().then(() => {
    e.respondWith(new Response('hi'));
  });
});

This should not throw because respondWith() is called while the event
dispatch flag is still set.

The microtask checkpoint is in "Cleanup After Running Scripts" here:
https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script

This is called from step 16.2 here:
https://heycam.github.io/webidl/#call-a-user-objects-operation

Which in turn is called from the DOM spec's "Inner Invoke" to call event
targets:
https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke

2.
Changes the expectation for:

addEventListener('message', event => {
  Promise.resolve().then(event.waitUntil(p));
});

From throws to not throws, for the same reasoning as above.

3.
Changes the expectation for:

addEventListener('message', event => {
  waitPromise = Promise.resolve();
  event.waitUntil(waitPromise);
  waitPromise.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  });
});

From throws to not throws. This is subtle. Because all the promises
are just Promise.resolve(), the event dispatch flag is still set
by the time the second waitUntil() is called.

4.
To test what 3. originally intended, a new test is
added which makes waitPromise a promise that does not immediately
resolve.

5.
Changes the expectation for:

addEventListener(‘fetch’, event => {
  response = Promise.resolve(new Response('RESP'));
  event.respondWith(response);
  response.then(() => {
    Promise.resolve().then(() => {event.waitUntil();});
  })
});

Again this is because the promises used resolve immediately,
so the event dispatch flag is still set.

Similarly, a new test is added to cover the original intent.

These WPT changes appear to match the behavior of Safari and Edge while
diverging from Chrome and (partially) Firefox.

[1] w3c/ServiceWorker#1213
[2] w3c/ServiceWorker#1394

Bug: 942414
Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393
Commit-Queue: Matt Falkenhagen <falkenchromium.org>
Reviewed-by: Ben Kelly <wanderviewchromium.org>
Cr-Commit-Position: refs/heads/master{#641514}
--

wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356
wpt-pr: 15852

UltraBlame original commit: b4b704c52ae96a9cdfbc3c4565a39d17f2480d19
ryanhaddad pushed a commit to WebKit/WebKit that referenced this issue Dec 22, 2020
https://bugs.webkit.org/show_bug.cgi?id=188246

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

This test is wrong[1,2]. It starts failing since our worker starts using correct microtask queues.

[1]: web-platform-tests/wpt#8936
[2]: w3c/ServiceWorker#1213 (comment)

* web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https-expected.txt:

Source/WebCore:

This patch adds the microtask mechanism to workers. To adopt the existing microtask mechanism from the main thread,
we extend JSMainThreadExecState for non-main-threads. We rename it to JSExecState, and store stacked
ExecState* data in thread local storage in ThreadGlobalData instead of a static variable s_mainThreadState.

We add MicrotaskQueue to WorkerGlobalScope since each worker has its own thread and it should have its
own microtask queue.

* Modules/encryptedmedia/legacy/LegacyCDMSessionClearKey.cpp:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSBindingsAllInOne.cpp:
* bindings/js/JSCallbackData.cpp:
(WebCore::JSCallbackData::invokeCallback):
* bindings/js/JSCustomElementInterface.cpp:
(WebCore::constructCustomElementSynchronously):
(WebCore::JSCustomElementInterface::upgradeElement):
(WebCore::JSCustomElementInterface::invokeCallback):
* bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
* bindings/js/JSDOMGlobalObjectTask.cpp:
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::queueTaskToEventLoop):
Queue a microtask to MicrotaskQueue instead of posting a macrotask.

(WebCore::JSDOMWindowMicrotaskCallback::create): Deleted.
(WebCore::JSDOMWindowMicrotaskCallback::call): Deleted.
(WebCore::JSDOMWindowMicrotaskCallback::JSDOMWindowMicrotaskCallback): Deleted.
(): Deleted.
Extract JSDOMWindowMicrotaskCallback as JSMicrotaskCallback and create a new file for it.

* bindings/js/JSErrorHandler.cpp:
(WebCore::JSErrorHandler::handleEvent):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/JSExecState.cpp: Renamed from Source/WebCore/bindings/js/JSMainThreadExecState.cpp.
(WebCore::JSExecState::didLeaveScriptContext):
If we are in a main thread, we consume main thread microtask queue. If we are in worker thread,
we consume a microtask queue per worker.

(WebCore::functionCallHandlerFromAnyThread):
(WebCore::evaluateHandlerFromAnyThread):
* bindings/js/JSExecState.h: Renamed from Source/WebCore/bindings/js/JSMainThreadExecState.h.
(WebCore::JSExecState::currentState):
(WebCore::JSExecState::call):
(WebCore::JSExecState::evaluate):
(WebCore::JSExecState::profiledCall):
(WebCore::JSExecState::profiledEvaluate):
(WebCore::JSExecState::runTask):
(WebCore::JSExecState::loadModule):
(WebCore::JSExecState::linkAndEvaluateModule):
(WebCore::JSExecState::JSExecState):
(WebCore::JSExecState::~JSExecState):
(WebCore::JSExecState::setCurrentState):
Store and load ExecState in thread local storage, ThreadGlobalData. This allows us to use it for workers.

(WebCore::JSMainThreadNullState::JSMainThreadNullState):
(WebCore::JSMainThreadNullState::~JSMainThreadNullState):
We keep this name "JSMainThreadNullState" since CustomElementReactionStack should be stick to the main thread.
And this class is only used in the main thread.

* bindings/js/JSExecStateInstrumentation.h: Renamed from Source/WebCore/bindings/js/JSMainThreadExecStateInstrumentation.h.
(WebCore::JSExecState::instrumentFunctionInternal):
(WebCore::JSExecState::instrumentFunctionCall):
(WebCore::JSExecState::instrumentFunctionConstruct):
* bindings/js/JSMicrotaskCallback.h: Copied from Source/WebKitLegacy/mac/DOM/DOMHTMLBaseElement.mm.
(WebCore::JSMicrotaskCallback::create):
(WebCore::JSMicrotaskCallback::call):
(WebCore::JSMicrotaskCallback::JSMicrotaskCallback):
* bindings/js/JSWorkerGlobalScopeBase.cpp:
(WebCore::JSWorkerGlobalScopeBase::queueTaskToEventLoop):
* bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::executeFunctionInContext):
* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::evaluateInWorld):
(WebCore::ScriptController::loadModuleScriptInWorld):
(WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld):
(WebCore::ScriptController::canAccessFromCurrentOrigin):
* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::evaluate):
* bridge/objc/WebScriptObject.mm:
(-[WebScriptObject callWebScriptMethod:withArguments:]):
(-[WebScriptObject evaluateWebScript:]):
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::compileShader):
(WebCore::WebGLRenderingContextBase::printToConsole):
* inspector/InspectorCanvas.cpp:
(WebCore::InspectorCanvas::buildObjectForCanvas):
(WebCore::InspectorCanvas::buildAction):
* inspector/InspectorController.cpp:
* inspector/InspectorFrontendHost.cpp:
* inspector/TimelineRecordFactory.cpp:
(WebCore::TimelineRecordFactory::createGenericRecord):
* inspector/WorkerInspectorController.cpp:
* inspector/agents/InspectorCanvasAgent.cpp:
* inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::buildInitiatorObject):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::postMessage):
* page/PageConsoleClient.cpp:
(WebCore::PageConsoleClient::addMessage):
* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::reportViolation const):
* platform/ThreadGlobalData.h:
(WebCore::ThreadGlobalData::ThreadGlobalData::currentState const):
(WebCore::ThreadGlobalData::ThreadGlobalData::setCurrentState):
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):
(WebCore::WorkerGlobalScope::removeMicrotaskQueue):
* workers/WorkerGlobalScope.h:
(WebCore::WorkerGlobalScope::microtaskQueue const):
* workers/WorkerThread.cpp:
(WebCore::WorkerThread::stop):
* workers/service/ExtendableEvent.cpp:
(WebCore::ExtendableEvent::addExtendLifetimePromise):
When dispatching an "install" event from service worker, we first create an event,
dispatch it, and set a handler which is called when a pending promise count becomes zero.
However, the old code checked pending promise count in a queued microtask. It worked
previously because microtask is actually a macrotask in the service worker. So this check
is done after a handler is set. But this patch introduces real microtask, and this check
happens before a handler is set because dispatching an event can exhaust microtask queue.
According to the spec, this check should not be done in microtask[1]. We make this checking
part as a macrotask. We note that algorithm noted as FIXMEs should be done in this
microtask while the checking part should not be done.

[1]: https://w3c.github.io/ServiceWorker/#installation-algorithm

Source/WebKit:

Rename JSMainThreadExecState.h to JSExecState.h.

* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMAttr.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMBlob.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCDATASection.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSRule.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSRuleList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSStyleDeclaration.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSStyleSheet.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSValue.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCharacterData.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMClientRect.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMClientRectList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMComment.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMImplementation.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMSelection.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMTokenList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMWindow.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDeprecated.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDocumentFragment.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDocumentGtk.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDocumentType.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMElementGtk.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMEvent.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMFile.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMFileList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLAnchorElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLAppletElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLAreaElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLBRElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLBaseElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLBodyElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLButtonElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLCanvasElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLCollection.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDListElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDirectoryElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDivElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDocument.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLEmbedElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFieldSetElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFontElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFormElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFrameElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFrameSetElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHRElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHeadElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHeadingElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHtmlElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLIFrameElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLImageElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLInputElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLIElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLabelElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLegendElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLinkElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMapElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMarqueeElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMenuElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMetaElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLModElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOListElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLObjectElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOptGroupElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOptionElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOptionsCollection.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLParagraphElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLParamElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLPreElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLQuoteElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLScriptElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLSelectElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLStyleElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCaptionElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCellElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableColElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableRowElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableSectionElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTextAreaElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTitleElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLUListElement.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMKeyboardEvent.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMMediaList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMMouseEvent.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNamedNodeMap.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNodeGtk.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNodeIterator.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNodeList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMProcessingInstruction.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMRange.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMStyleSheet.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMStyleSheetList.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMText.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMTreeWalker.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMUIEvent.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMWheelEvent.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMXPathExpression.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMXPathNSResolver.cpp:
* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMXPathResult.cpp:

Source/WebKitLegacy/mac:

Rename JSMainThreadExecState.h to JSExecState.h.

* DOM/DOMAttr.mm:
* DOM/DOMBlob.mm:
* DOM/DOMCDATASection.mm:
* DOM/DOMCSSCharsetRule.mm:
* DOM/DOMCSSFontFaceRule.mm:
* DOM/DOMCSSImportRule.mm:
* DOM/DOMCSSMediaRule.mm:
* DOM/DOMCSSPageRule.mm:
* DOM/DOMCSSPrimitiveValue.mm:
* DOM/DOMCSSRule.mm:
* DOM/DOMCSSRuleList.mm:
* DOM/DOMCSSStyleDeclaration.mm:
* DOM/DOMCSSStyleRule.mm:
* DOM/DOMCSSStyleSheet.mm:
* DOM/DOMCSSUnknownRule.mm:
* DOM/DOMCSSValue.mm:
* DOM/DOMCSSValueList.mm:
* DOM/DOMCharacterData.mm:
* DOM/DOMComment.mm:
* DOM/DOMCounter.mm:
* DOM/DOMDocument.mm:
* DOM/DOMDocumentFragment.mm:
* DOM/DOMDocumentType.mm:
* DOM/DOMElement.mm:
* DOM/DOMEvent.mm:
* DOM/DOMFile.mm:
* DOM/DOMFileList.mm:
* DOM/DOMHTML.mm:
* DOM/DOMHTMLAnchorElement.mm:
* DOM/DOMHTMLAppletElement.mm:
* DOM/DOMHTMLAreaElement.mm:
* DOM/DOMHTMLBRElement.mm:
* DOM/DOMHTMLBaseElement.mm:
* DOM/DOMHTMLBaseFontElement.mm:
* DOM/DOMHTMLBodyElement.mm:
* DOM/DOMHTMLButtonElement.mm:
* DOM/DOMHTMLCanvasElement.mm:
* DOM/DOMHTMLCollection.mm:
* DOM/DOMHTMLDListElement.mm:
* DOM/DOMHTMLDirectoryElement.mm:
* DOM/DOMHTMLDivElement.mm:
* DOM/DOMHTMLDocument.mm:
* DOM/DOMHTMLElement.mm:
* DOM/DOMHTMLEmbedElement.mm:
* DOM/DOMHTMLFieldSetElement.mm:
* DOM/DOMHTMLFontElement.mm:
* DOM/DOMHTMLFormElement.mm:
* DOM/DOMHTMLFrameElement.mm:
* DOM/DOMHTMLFrameSetElement.mm:
* DOM/DOMHTMLHRElement.mm:
* DOM/DOMHTMLHeadElement.mm:
* DOM/DOMHTMLHeadingElement.mm:
* DOM/DOMHTMLHtmlElement.mm:
* DOM/DOMHTMLIFrameElement.mm:
* DOM/DOMHTMLImageElement.mm:
* DOM/DOMHTMLInputElement.mm:
* DOM/DOMHTMLLIElement.mm:
* DOM/DOMHTMLLabelElement.mm:
* DOM/DOMHTMLLegendElement.mm:
* DOM/DOMHTMLLinkElement.mm:
* DOM/DOMHTMLMapElement.mm:
* DOM/DOMHTMLMarqueeElement.mm:
* DOM/DOMHTMLMediaElement.mm:
* DOM/DOMHTMLMenuElement.mm:
* DOM/DOMHTMLMetaElement.mm:
* DOM/DOMHTMLModElement.mm:
* DOM/DOMHTMLOListElement.mm:
* DOM/DOMHTMLObjectElement.mm:
* DOM/DOMHTMLOptGroupElement.mm:
* DOM/DOMHTMLOptionElement.mm:
* DOM/DOMHTMLOptionsCollection.mm:
* DOM/DOMHTMLParagraphElement.mm:
* DOM/DOMHTMLParamElement.mm:
* DOM/DOMHTMLPreElement.mm:
* DOM/DOMHTMLQuoteElement.mm:
* DOM/DOMHTMLScriptElement.mm:
* DOM/DOMHTMLSelectElement.mm:
* DOM/DOMHTMLStyleElement.mm:
* DOM/DOMHTMLTableCaptionElement.mm:
* DOM/DOMHTMLTableCellElement.mm:
* DOM/DOMHTMLTableColElement.mm:
* DOM/DOMHTMLTableElement.mm:
* DOM/DOMHTMLTableRowElement.mm:
* DOM/DOMHTMLTableSectionElement.mm:
* DOM/DOMHTMLTextAreaElement.mm:
* DOM/DOMHTMLTitleElement.mm:
* DOM/DOMHTMLUListElement.mm:
* DOM/DOMHTMLVideoElement.mm:
* DOM/DOMImplementation.mm:
* DOM/DOMKeyboardEvent.mm:
* DOM/DOMMediaError.mm:
* DOM/DOMMediaList.mm:
* DOM/DOMMouseEvent.mm:
* DOM/DOMMutationEvent.mm:
* DOM/DOMNamedNodeMap.mm:
* DOM/DOMNode.mm:
* DOM/DOMNodeIterator.mm:
* DOM/DOMNodeList.mm:
* DOM/DOMOverflowEvent.mm:
* DOM/DOMProcessingInstruction.mm:
* DOM/DOMProgressEvent.mm:
* DOM/DOMRGBColor.mm:
* DOM/DOMRange.mm:
* DOM/DOMRect.mm:
* DOM/DOMStyleSheet.mm:
* DOM/DOMStyleSheetList.mm:
* DOM/DOMText.mm:
* DOM/DOMTextEvent.mm:
* DOM/DOMTimeRanges.mm:
* DOM/DOMTokenList.mm:
* DOM/DOMTreeWalker.mm:
* DOM/DOMUIEvent.mm:
* DOM/DOMWheelEvent.mm:
* DOM/DOMXPathExpression.mm:
* DOM/DOMXPathResult.mm:
* DOM/ObjCEventListener.mm:

LayoutTests:

* http/wpt/workers/microtasks.any-expected.txt: Added.
* http/wpt/workers/microtasks.any.html: Added.
* http/wpt/workers/microtasks.any.js: Added.
(promise_test):
* http/wpt/workers/microtasks.any.worker-expected.txt: Added.
* http/wpt/workers/microtasks.any.worker.html: Added.

Canonical link: https://commits.webkit.org/203435@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234586 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants