Use the event loop instead of DocumentEventQueue and WorkerEventQueue
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 23 Nov 2019 04:28:46 +0000 (04:28 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 23 Nov 2019 04:28:46 +0000 (04:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204447
<rdar://problem/57420691>

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Updated the expected result. It now fails one step head due to EventLoop getting better integrated with timers.

* web-platform-tests/requestidlecallback/callback-timeout-when-busy-expected.txt:

Source/WebCore:

This patch replaces every use of DocumentEventQueue and WorkerEventQueue by the integration
with the event loop.

Because this changes the order by which some of the affected events fire and tasks run,
this patch also makes WindowEventLoop::scheduleToRun use a Timer instead of callOnMainThread
in order to avoid introducing new test failures.

In addition, WebSQL needed a code change to scheudle tasks via the event loop after moving
to the event loop as callOnMainThread could run before or after a 0s timer fires depending
on whether it was called during another timer or not; meaning that it could change the order
of operations with respect to other tasks scheduled via event loops in some cases.

Finally, added the links to various specifications where appropriate.

* Modules/indexeddb/IDBDatabase.cpp:
(WebCore::IDBDatabase::connectionToServerLost):
(WebCore::IDBDatabase::fireVersionChangeEvent):
* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::enqueueEvent):
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::enqueueEvent):
(WebCore::IDBTransaction::dispatchEvent):
* Modules/mediastream/RTCDataChannel.cpp:
(WebCore::RTCDataChannel::scheduleDispatchEvent):
* Modules/webdatabase/Database.cpp:
(WebCore::Database::scheduleTransactionCallback): Schedule a task on the event loop once
we're in the main thread as the order of operation could change with respect to other tasks
scheduled via the event loop otherwise.
* Modules/webdatabase/SQLTransaction.cpp:
(WebCore::SQLTransaction::notifyDatabaseThreadIsShuttingDown): Ditto.
* dom/Document.cpp:
(WebCore::Document::visibilityStateChanged):
(WebCore::Document::prepareForDestruction):
(WebCore::Document::enqueueWindowEvent): Deleted.
(WebCore::Document::queueTaskToDispatchEvent): Added.
(WebCore::Document::enqueueDocumentEvent): Deleted.
(WebCore::Document::queueTaskToDispatchEventOnWindow): Added.
(WebCore::Document::enqueueOverflowEvent):
(WebCore::Document::enqueueSecurityPolicyViolationEvent):
(WebCore::Document::enqueueHashchangeEvent): Rewritten. Keep the target node alive until
the overflow event fires.
fired on an overflow element
* dom/Document.h:
* dom/ScriptExecutionContext.h:
* dom/TaskSource.h:
* dom/WindowEventLoop.cpp:
(WebCore::WindowEventLoop::WindowEventLoop):
(WebCore::WindowEventLoop::scheduleToRun):
* dom/WindowEventLoop.h:
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::setSelectionWithoutUpdatingAppearance):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::languagesChanged):
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::elementWasRemoved):
* page/PointerLockController.cpp:
(WebCore::PointerLockController::enqueueEvent):
* storage/StorageEventDispatcher.cpp:
(WebCore::StorageEventDispatcher::dispatchSessionStorageEventsToFrames):
(WebCore::StorageEventDispatcher::dispatchLocalStorageEventsToFrames):
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):
(WebCore::WorkerGlobalScope::eventQueue const): Deleted.
* workers/WorkerGlobalScope.h:
* worklets/WorkletGlobalScope.cpp:
(WebCore::WorkletGlobalScope::WorkletGlobalScope):
* worklets/WorkletGlobalScope.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@252824 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/requestidlecallback/callback-timeout-when-busy-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBDatabase.cpp
Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
Source/WebCore/Modules/mediastream/RTCDataChannel.cpp
Source/WebCore/Modules/webdatabase/Database.cpp
Source/WebCore/Modules/webdatabase/SQLTransaction.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/ScriptExecutionContext.h
Source/WebCore/dom/TaskSource.h
Source/WebCore/dom/WindowEventLoop.cpp
Source/WebCore/dom/WindowEventLoop.h
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/PointerCaptureController.cpp
Source/WebCore/page/PointerLockController.cpp
Source/WebCore/storage/StorageEventDispatcher.cpp
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h
Source/WebCore/worklets/WorkletGlobalScope.cpp
Source/WebCore/worklets/WorkletGlobalScope.h

index 941ff5a..a1c7678 100644 (file)
@@ -1,3 +1,15 @@
+2019-11-21  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Use the event loop instead of DocumentEventQueue and WorkerEventQueue
+        https://bugs.webkit.org/show_bug.cgi?id=204447
+        <rdar://problem/57420691>
+
+        Reviewed by Antti Koivisto.
+
+        Updated the expected result. It now fails one step head due to EventLoop getting better integrated with timers.
+
+        * web-platform-tests/requestidlecallback/callback-timeout-when-busy-expected.txt:
+
 2019-11-20  Simon Fraser  <simon.fraser@apple.com>
 
         getComputedStyle returns "auto" for zIndex property even after it has been set, on non-positioned elements
index 19a49ca..4a3d2d4 100644 (file)
@@ -2,5 +2,5 @@ Test of requestIdleCallback timeout behavior
 
 
 FAIL requestIdleCallback not scheduled when event loop is busy. assert_false: IdleDeadline.didTimeout MUST be false if requestIdleCallback wasn't scheduled due to a timeout expected false got true
-FAIL requestIdleCallback scheduled with timeout when event loop is busy. assert_true: Should only have been run after timeout expected true got false
+FAIL requestIdleCallback scheduled with timeout when event loop is busy. assert_true: IdleDeadline.timeRemaining MUST be equal to zero if requestIdleCallback was scheduled due to a timeout expected true got false
 
index ac31281..f322293 100644 (file)
@@ -1,3 +1,79 @@
+2019-11-21  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Use the event loop instead of DocumentEventQueue and WorkerEventQueue
+        https://bugs.webkit.org/show_bug.cgi?id=204447
+        <rdar://problem/57420691>
+
+        Reviewed by Antti Koivisto.
+
+        This patch replaces every use of DocumentEventQueue and WorkerEventQueue by the integration
+        with the event loop.
+
+        Because this changes the order by which some of the affected events fire and tasks run,
+        this patch also makes WindowEventLoop::scheduleToRun use a Timer instead of callOnMainThread
+        in order to avoid introducing new test failures.
+
+        In addition, WebSQL needed a code change to scheudle tasks via the event loop after moving
+        to the event loop as callOnMainThread could run before or after a 0s timer fires depending
+        on whether it was called during another timer or not; meaning that it could change the order
+        of operations with respect to other tasks scheduled via event loops in some cases.
+
+        Finally, added the links to various specifications where appropriate.
+
+        * Modules/indexeddb/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::connectionToServerLost):
+        (WebCore::IDBDatabase::fireVersionChangeEvent):
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::enqueueEvent):
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::enqueueEvent):
+        (WebCore::IDBTransaction::dispatchEvent):
+        * Modules/mediastream/RTCDataChannel.cpp:
+        (WebCore::RTCDataChannel::scheduleDispatchEvent):
+        * Modules/webdatabase/Database.cpp:
+        (WebCore::Database::scheduleTransactionCallback): Schedule a task on the event loop once
+        we're in the main thread as the order of operation could change with respect to other tasks
+        scheduled via the event loop otherwise.
+        * Modules/webdatabase/SQLTransaction.cpp:
+        (WebCore::SQLTransaction::notifyDatabaseThreadIsShuttingDown): Ditto.
+        * dom/Document.cpp:
+        (WebCore::Document::visibilityStateChanged):
+        (WebCore::Document::prepareForDestruction):
+        (WebCore::Document::enqueueWindowEvent): Deleted.
+        (WebCore::Document::queueTaskToDispatchEvent): Added.
+        (WebCore::Document::enqueueDocumentEvent): Deleted.
+        (WebCore::Document::queueTaskToDispatchEventOnWindow): Added.
+        (WebCore::Document::enqueueOverflowEvent):
+        (WebCore::Document::enqueueSecurityPolicyViolationEvent):
+        (WebCore::Document::enqueueHashchangeEvent): Rewritten. Keep the target node alive until
+        the overflow event fires.
+        fired on an overflow element 
+        * dom/Document.h:
+        * dom/ScriptExecutionContext.h:
+        * dom/TaskSource.h:
+        * dom/WindowEventLoop.cpp:
+        (WebCore::WindowEventLoop::WindowEventLoop):
+        (WebCore::WindowEventLoop::scheduleToRun):
+        * dom/WindowEventLoop.h:
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setSelectionWithoutUpdatingAppearance):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::languagesChanged):
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::elementWasRemoved):
+        * page/PointerLockController.cpp:
+        (WebCore::PointerLockController::enqueueEvent):
+        * storage/StorageEventDispatcher.cpp:
+        (WebCore::StorageEventDispatcher::dispatchSessionStorageEventsToFrames):
+        (WebCore::StorageEventDispatcher::dispatchLocalStorageEventsToFrames):
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
+        (WebCore::WorkerGlobalScope::eventQueue const): Deleted.
+        * workers/WorkerGlobalScope.h:
+        * worklets/WorkletGlobalScope.cpp:
+        (WebCore::WorkletGlobalScope::WorkletGlobalScope):
+        * worklets/WorkletGlobalScope.h:
+
 2019-11-22  Ryosuke Niwa  <rniwa@webkit.org>
 
         REGRESSION (r252792?): 6 inspector/canvas tests crashing
index db649b9..cf4a102 100644 (file)
@@ -279,13 +279,13 @@ void IDBDatabase::connectionToServerLost(const IDBError& error)
     errorEvent->setTarget(this);
 
     if (auto* context = scriptExecutionContext())
-        context->eventQueue().enqueueEvent(WTFMove(errorEvent));
+        queueTaskToDispatchEvent(*this, TaskSource::DatabaseAccess, WTFMove(errorEvent));
 
     auto closeEvent = Event::create(m_eventNames.closeEvent, Event::CanBubble::Yes, Event::IsCancelable::No);
     closeEvent->setTarget(this);
 
     if (auto* context = scriptExecutionContext())
-        context->eventQueue().enqueueEvent(WTFMove(closeEvent));
+        queueTaskToDispatchEvent(*this, TaskSource::DatabaseAccess, WTFMove(closeEvent));
 }
 
 void IDBDatabase::maybeCloseInServer()
@@ -468,8 +468,7 @@ void IDBDatabase::fireVersionChangeEvent(const IDBResourceIdentifier& requestIde
     }
     
     Ref<Event> event = IDBVersionChangeEvent::create(requestIdentifier, currentVersion, requestedVersion, m_eventNames.versionchangeEvent);
-    event->setTarget(this);
-    scriptExecutionContext()->eventQueue().enqueueEvent(WTFMove(event));
+    queueTaskToDispatchEvent(*this, TaskSource::DatabaseAccess, WTFMove(event));
 }
 
 void IDBDatabase::dispatchEvent(Event& event)
index 82b373f..80ce424 100644 (file)
@@ -290,8 +290,7 @@ void IDBRequest::enqueueEvent(Ref<Event>&& event)
     if (m_contextStopped)
         return;
 
-    event->setTarget(this);
-    scriptExecutionContext()->eventQueue().enqueueEvent(WTFMove(event));
+    queueTaskToDispatchEvent(*this, TaskSource::DatabaseAccess, WTFMove(event));
 }
 
 void IDBRequest::dispatchEvent(Event& event)
index 006c741..e32f962 100644 (file)
@@ -625,8 +625,7 @@ void IDBTransaction::enqueueEvent(Ref<Event>&& event)
     if (!scriptExecutionContext() || m_contextStopped)
         return;
 
-    event->setTarget(this);
-    scriptExecutionContext()->eventQueue().enqueueEvent(WTFMove(event));
+    queueTaskToDispatchEvent(*this, TaskSource::DatabaseAccess, WTFMove(event));
 }
 
 void IDBTransaction::dispatchEvent(Event& event)
@@ -636,7 +635,6 @@ void IDBTransaction::dispatchEvent(Event& event)
     ASSERT(canCurrentThreadAccessThreadLocalData(m_database->originThread()));
     ASSERT(scriptExecutionContext());
     ASSERT(!m_contextStopped);
-    ASSERT(event.target() == this);
     ASSERT(event.type() == eventNames().completeEvent || event.type() == eventNames().abortEvent);
 
     auto protectedThis = makeRef(*this);
index ad0cb14..6a0df04 100644 (file)
@@ -230,8 +230,8 @@ void RTCDataChannel::scheduleDispatchEvent(Ref<Event>&& event)
     if (m_stopped)
         return;
 
-    event->setTarget(this);
-    scriptExecutionContext()->eventQueue().enqueueEvent(WTFMove(event));
+    // https://w3c.github.io/webrtc-pc/#operation
+    queueTaskToDispatchEvent(*this, TaskSource::Networking, WTFMove(event));
 }
 
 } // namespace WebCore
index 7bf3d2f..218b0c4 100644 (file)
@@ -703,8 +703,10 @@ void Database::runTransaction(RefPtr<SQLTransactionCallback>&& callback, RefPtr<
 
 void Database::scheduleTransactionCallback(SQLTransaction* transaction)
 {
-    callOnMainThread([transaction = makeRefPtr(transaction)] {
-        transaction->performPendingCallback();
+    callOnMainThread([this, protectedThis = makeRef(*this), transaction = makeRefPtr(transaction)] {
+        m_document->eventLoop().queueTask(TaskSource::Networking, [transaction = transaction.copyRef()] {
+            transaction->performPendingCallback();
+        });
     });
 }
 
index 79d2347..dd65d86 100644 (file)
@@ -128,7 +128,9 @@ void SQLTransaction::performPendingCallback()
 void SQLTransaction::notifyDatabaseThreadIsShuttingDown()
 {
     callOnMainThread([this, protectedThis = makeRef(*this)]() mutable {
-        callErrorCallbackDueToInterruption();
+        m_database->document().eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = protectedThis.copyRef()]() mutable {
+            callErrorCallbackDueToInterruption();
+        });
     });
 
     m_backend.notifyDatabaseThreadIsShuttingDown();
index e6bb792..cd55f86 100644 (file)
@@ -554,7 +554,6 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig
     , m_xmlVersion("1.0"_s)
     , m_constantPropertyMap(makeUnique<ConstantPropertyMap>(*this))
     , m_documentClasses(documentClasses)
-    , m_eventQueue(*this)
 #if ENABLE(FULLSCREEN_API)
     , m_fullscreenManager { makeUniqueRef<FullscreenManager>(*this) }
 #endif
@@ -1707,7 +1706,8 @@ void Document::unregisterForVisibilityStateChangedCallbacks(VisibilityChangeClie
 
 void Document::visibilityStateChanged()
 {
-    enqueueDocumentEvent(Event::create(eventNames().visibilitychangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+    // // https://w3c.github.io/page-visibility/#reacting-to-visibilitychange-changes
+    queueTaskToDispatchEvent(TaskSource::UserInteraction, Event::create(eventNames().visibilitychangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
     for (auto* client : m_visibilityStateCallbackClients)
         client->visibilityStateChanged();
 
@@ -2532,7 +2532,6 @@ void Document::prepareForDestruction()
     InspectorInstrumentation::documentDetached(*this);
 
     stopActiveDOMObjects();
-    m_eventQueue.close();
 #if ENABLE(FULLSCREEN_API)
     m_fullscreenManager->emptyEventQueue();
 #endif
@@ -4737,21 +4736,32 @@ void Document::dispatchWindowLoadEvent()
     m_cachedResourceLoader->documentDidFinishLoadEvent();
 }
 
-void Document::enqueueWindowEvent(Ref<Event>&& event)
+void Document::queueTaskToDispatchEvent(TaskSource source, Ref<Event>&& event)
 {
-    event->setTarget(m_domWindow.get());
-    m_eventQueue.enqueueEvent(WTFMove(event));
+    eventLoop().queueTask(source, [document = makeRef(*this), event = WTFMove(event)] {
+        document->dispatchEvent(event);
+    });
 }
 
-void Document::enqueueDocumentEvent(Ref<Event>&& event)
+void Document::queueTaskToDispatchEventOnWindow(TaskSource source, Ref<Event>&& event)
 {
-    event->setTarget(this);
-    m_eventQueue.enqueueEvent(WTFMove(event));
+    eventLoop().queueTask(source, [this, protectedThis = makeRef(*this), event = WTFMove(event)] {
+        if (!m_domWindow)
+            return;
+        m_domWindow->dispatchEvent(event);
+    });
 }
 
 void Document::enqueueOverflowEvent(Ref<Event>&& event)
 {
-    m_eventQueue.enqueueEvent(WTFMove(event));
+    // https://developer.mozilla.org/en-US/docs/Web/API/Element/overflow_event
+    // FIXME: This event is totally unspecified.
+    auto* target = event->target();
+    RELEASE_ASSERT(target);
+    RELEASE_ASSERT(is<Node>(target));
+    eventLoop().queueTask(TaskSource::DOMManipulation, [protectedTarget = GCReachableRef<Node>(downcast<Node>(*target)), event = WTFMove(event)] {
+        protectedTarget->dispatchEvent(event);
+    });
 }
 
 ExceptionOr<Ref<Event>> Document::createEvent(const String& type)
@@ -6372,12 +6382,13 @@ void Document::dispatchPageshowEvent(PageshowEventPersistence persisted)
 
 void Document::enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&& eventInit)
 {
-    enqueueDocumentEvent(SecurityPolicyViolationEvent::create(eventNames().securitypolicyviolationEvent, WTFMove(eventInit), Event::IsTrusted::Yes));
+    queueTaskToDispatchEvent(TaskSource::DOMManipulation, SecurityPolicyViolationEvent::create(eventNames().securitypolicyviolationEvent, WTFMove(eventInit), Event::IsTrusted::Yes));
 }
 
 void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
 {
-    enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
+    // FIXME: popstate event and hashchange event are supposed to fire in a single task.
+    queueTaskToDispatchEventOnWindow(TaskSource::DOMManipulation, HashChangeEvent::create(oldURL, newURL));
 }
 
 void Document::dispatchPopstateEvent(RefPtr<SerializedScriptValue>&& stateObject)
index 47ddb9e..c5d1970 100644 (file)
@@ -1168,14 +1168,13 @@ public:
     bool isSecureContext() const final;
     bool isJSExecutionForbidden() const final { return false; }
 
-    void enqueueWindowEvent(Ref<Event>&&);
-    void enqueueDocumentEvent(Ref<Event>&&);
+    void queueTaskToDispatchEvent(TaskSource, Ref<Event>&&);
+    void queueTaskToDispatchEventOnWindow(TaskSource, Ref<Event>&&);
     void enqueueOverflowEvent(Ref<Event>&&);
     void dispatchPageshowEvent(PageshowEventPersistence);
     WEBCORE_EXPORT void enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&&);
     void enqueueHashchangeEvent(const String& oldURL, const String& newURL);
     void dispatchPopstateEvent(RefPtr<SerializedScriptValue>&& stateObject);
-    DocumentEventQueue& eventQueue() const final { return m_eventQueue; }
 
     WEBCORE_EXPORT void addMediaCanStartListener(MediaCanStartListener&);
     WEBCORE_EXPORT void removeMediaCanStartListener(MediaCanStartListener&);
@@ -1825,7 +1824,6 @@ private:
     DocumentClassFlags m_documentClasses;
 
     RenderPtr<RenderView> m_renderView;
-    mutable DocumentEventQueue m_eventQueue;
 
     HashSet<MediaCanStartListener*> m_mediaCanStartListeners;
 
index fbbacd5..94b6b3c 100644 (file)
@@ -217,7 +217,6 @@ public:
     void didChangeTimerAlignmentInterval();
     virtual Seconds domTimerAlignmentInterval(bool hasReachedMaxNestingLevel) const;
 
-    virtual EventQueue& eventQueue() const = 0;
     virtual EventTarget* errorEventTarget() = 0;
 
     DatabaseContext* databaseContext() { return m_databaseContext.get(); }
index e3b129e..143885c 100644 (file)
@@ -29,6 +29,7 @@ namespace WebCore {
 
 enum class TaskSource : uint8_t {
     DOMManipulation,
+    DatabaseAccess,
     FileReading,
     FontLoading,
     IdleTask,
index 16c8304..b8ad194 100644 (file)
@@ -52,6 +52,7 @@ Ref<WindowEventLoop> WindowEventLoop::ensureForRegistrableDomain(const Registrab
 
 inline WindowEventLoop::WindowEventLoop(const RegistrableDomain& domain)
     : m_domain(domain)
+    , m_timer(*this, &WindowEventLoop::run)
 {
 }
 
@@ -63,9 +64,7 @@ WindowEventLoop::~WindowEventLoop()
 
 void WindowEventLoop::scheduleToRun()
 {
-    callOnMainThread([eventLoop = makeRef(*this)] () {
-        eventLoop->run();
-    });
+    m_timer.startOneShot(0_s);
 }
 
 bool WindowEventLoop::isContextThread() const
index bed10d0..1196ad6 100644 (file)
@@ -28,6 +28,7 @@
 #include "DocumentIdentifier.h"
 #include "EventLoop.h"
 #include "RegistrableDomain.h"
+#include "Timer.h"
 #include <wtf/HashSet.h>
 
 namespace WebCore {
@@ -49,6 +50,7 @@ private:
     MicrotaskQueue& microtaskQueue() final;
 
     RegistrableDomain m_domain;
+    Timer m_timer;
 };
 
 } // namespace WebCore
index 8ae1625..f1e9a0d 100644 (file)
@@ -377,7 +377,9 @@ bool FrameSelection::setSelectionWithoutUpdatingAppearance(const VisibleSelectio
     m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation();
     selectFrameElementInParentIfFullySelected();
     m_frame->editor().respondToChangedSelection(oldSelection, options);
-    m_frame->document()->enqueueDocumentEvent(Event::create(eventNames().selectionchangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+    // https://www.w3.org/TR/selection-api/#selectionchange-event
+    // FIXME: Spec doesn't specify which task source to use.
+    m_frame->document()->queueTaskToDispatchEvent(TaskSource::UserInteraction, Event::create(eventNames().selectionchangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
 
     return true;
 }
index 494e097..0568b06 100644 (file)
@@ -2124,8 +2124,9 @@ bool DOMWindow::removeEventListener(const AtomString& eventType, EventListener&
 
 void DOMWindow::languagesChanged()
 {
-    if (auto* document = this->document())
-        document->enqueueWindowEvent(Event::create(eventNames().languagechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+    // https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-languages
+    if (auto document = makeRefPtr(this->document()))
+        document->queueTaskToDispatchEventOnWindow(TaskSource::DOMManipulation, Event::create(eventNames().languagechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
 }
 
 void DOMWindow::dispatchLoadEvent()
index 16f432a..04cc229 100644 (file)
@@ -150,7 +150,8 @@ void PointerCaptureController::elementWasRemoved(Element& element)
             auto pointerId = static_cast<PointerID>(keyAndValue.key);
             auto pointerType = capturingData.pointerType;
             releasePointerCapture(&element, pointerId);
-            element.document().enqueueDocumentEvent(PointerEvent::create(eventNames().lostpointercaptureEvent, pointerId, pointerType));
+            // FIXME: Spec doesn't specify which task soruce to use.
+            element.document().queueTaskToDispatchEvent(TaskSource::UserInteraction, PointerEvent::create(eventNames().lostpointercaptureEvent, pointerId, pointerType));
             return;
         }
     }
index 2fda513..608d4a8 100644 (file)
@@ -215,8 +215,9 @@ void PointerLockController::enqueueEvent(const AtomString& type, Element* elemen
 
 void PointerLockController::enqueueEvent(const AtomString& type, Document* document)
 {
-    if (document)
-        document->enqueueDocumentEvent(Event::create(type, Event::CanBubble::Yes, Event::IsCancelable::No));
+    // FIXME: Spec doesn't specify which task source use.
+    if (auto protectedDocument = makeRefPtr(document))
+        protectedDocument->queueTaskToDispatchEvent(TaskSource::UserInteraction, Event::create(type, Event::CanBubble::Yes, Event::IsCancelable::No));
 }
 
 } // namespace WebCore
index 9214274..5a569fc 100644 (file)
@@ -85,11 +85,10 @@ void StorageEventDispatcher::dispatchSessionStorageEventsToFrames(Page& page, co
     InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, StorageType::Session, securityOrigin.securityOrigin().ptr());
 
     for (auto& frame : frames) {
-        auto result = frame->document()->domWindow()->sessionStorage();
-        if (!frame->document())
-            continue;
-        if (!result.hasException())
-            frame->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
+        auto document = makeRefPtr(frame->document());
+        auto result = document->domWindow()->sessionStorage();
+        if (!result.hasException()) // https://html.spec.whatwg.org/multipage/webstorage.html#the-storage-event:event-storage
+            document->queueTaskToDispatchEventOnWindow(TaskSource::DOMManipulation, StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
     }
 }
 
@@ -99,11 +98,10 @@ void StorageEventDispatcher::dispatchLocalStorageEventsToFrames(PageGroup& pageG
         InspectorInstrumentation::didDispatchDOMStorageEvent(*page, key, oldValue, newValue, StorageType::Local, securityOrigin.securityOrigin().ptr());
 
     for (auto& frame : frames) {
-        auto result = frame->document()->domWindow()->localStorage();
-        if (!frame->document())
-            continue;
-        if (!result.hasException())
-            frame->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
+        auto document = makeRefPtr(frame->document());
+        auto result = document->domWindow()->localStorage();
+        if (!result.hasException()) // https://html.spec.whatwg.org/multipage/webstorage.html#the-storage-event:event-storage
+            document->queueTaskToDispatchEventOnWindow(TaskSource::DOMManipulation, StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
     }
 }
 
index 1d4e728..1a0d6a7 100644 (file)
@@ -70,7 +70,6 @@ WorkerGlobalScope::WorkerGlobalScope(const URL& url, Ref<SecurityOrigin>&& origi
     , m_inspectorController(makeUnique<WorkerInspectorController>(*this))
     , m_isOnline(isOnline)
     , m_shouldBypassMainWorldContentSecurityPolicy(shouldBypassMainWorldContentSecurityPolicy)
-    , m_eventQueue(*this)
     , m_topOrigin(WTFMove(topOrigin))
 #if ENABLE(INDEXED_DATABASE)
     , m_connectionProxy(connectionProxy)
@@ -414,11 +413,6 @@ bool WorkerGlobalScope::isJSExecutionForbidden() const
     return m_script->isExecutionForbidden();
 }
 
-WorkerEventQueue& WorkerGlobalScope::eventQueue() const
-{
-    return m_eventQueue;
-}
-
 #if ENABLE(WEB_CRYPTO)
 
 class CryptoBufferContainer : public ThreadSafeRefCounted<CryptoBufferContainer> {
index 7ad606e..ad58f26 100644 (file)
@@ -34,7 +34,6 @@
 #include "Supplementable.h"
 #include <wtf/URL.h>
 #include "WorkerCacheStorageConnection.h"
-#include "WorkerEventQueue.h"
 #include "WorkerMessagePortChannelProvider.h"
 #include "WorkerScriptController.h"
 #include <JavaScriptCore/ConsoleMessage.h>
@@ -161,7 +160,6 @@ private:
     void disableEval(const String& errorMessage) final;
     void disableWebAssembly(const String& errorMessage) final;
     EventTarget* errorEventTarget() final;
-    WorkerEventQueue& eventQueue() const final;
     String resourceRequestIdentifier() const final { return m_identifier; }
     SocketProvider* socketProvider() final;
 
@@ -196,8 +194,6 @@ private:
     RefPtr<WorkerEventLoop> m_eventLoop;
     std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
 
-    mutable WorkerEventQueue m_eventQueue;
-
     Ref<SecurityOrigin> m_topOrigin;
 
 #if ENABLE(INDEXED_DATABASE)
index c4bdaaf..a34ade9 100644 (file)
@@ -51,7 +51,6 @@ WorkletGlobalScope::WorkletGlobalScope(Document& document, ScriptSourceCode&& co
     : m_document(makeWeakPtr(document))
     , m_script(makeUnique<WorkletScriptController>(this))
     , m_topOrigin(SecurityOrigin::createUnique())
-    , m_eventQueue(*this)
     , m_code(WTFMove(code))
 {
     auto addResult = allWorkletGlobalScopesSet().add(this);
index 636f31a..0aa12dc 100644 (file)
@@ -117,7 +117,6 @@ private:
     void addConsoleMessage(MessageSource, MessageLevel, const String&, unsigned long) final;
 
     EventTarget* errorEventTarget() final { return this; }
-    EventQueue& eventQueue() const final { ASSERT_NOT_REACHED(); return m_eventQueue; }
 
 #if ENABLE(WEB_CRYPTO)
     bool wrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) final { RELEASE_ASSERT_NOT_REACHED(); return false; }
@@ -137,10 +136,6 @@ private:
     RefPtr<WorkerEventLoop> m_eventLoop;
     std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
 
-    // FIXME: This is not implemented properly, it just satisfies the compiler.
-    // https://bugs.webkit.org/show_bug.cgi?id=191136
-    mutable WorkerEventQueue m_eventQueue;
-
     JSC::RuntimeFlags m_jsRuntimeFlags;
     ScriptSourceCode m_code;
 };