diff options
Diffstat (limited to 'dom/workers/MessageEventRunnable.cpp')
-rw-r--r-- | dom/workers/MessageEventRunnable.cpp | 112 |
1 files changed, 95 insertions, 17 deletions
diff --git a/dom/workers/MessageEventRunnable.cpp b/dom/workers/MessageEventRunnable.cpp index 8edc7037cd..33efc966b4 100644 --- a/dom/workers/MessageEventRunnable.cpp +++ b/dom/workers/MessageEventRunnable.cpp @@ -14,9 +14,8 @@ namespace mozilla::dom { -MessageEventRunnable::MessageEventRunnable(WorkerPrivate* aWorkerPrivate, - Target aTarget) - : WorkerDebuggeeRunnable(aWorkerPrivate, "MessageEventRunnable", aTarget), +MessageEventRunnable::MessageEventRunnable(WorkerPrivate* aWorkerPrivate) + : WorkerDebuggeeRunnable("MessageEventRunnable"), StructuredCloneHolder(CloningSupported, TransferringSupported, StructuredCloneScope::SameProcess) {} @@ -84,20 +83,6 @@ bool MessageEventRunnable::DispatchDOMEvent(JSContext* aCx, bool MessageEventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { - if (mTarget == ParentThread) { - // Don't fire this event if the JS object has been disconnected from the - // private object. - if (!aWorkerPrivate->IsAcceptingEvents()) { - return true; - } - - aWorkerPrivate->AssertInnerWindowIsCorrect(); - - return DispatchDOMEvent(aCx, aWorkerPrivate, - aWorkerPrivate->ParentEventTargetRef(), - !aWorkerPrivate->GetParent()); - } - MOZ_ASSERT(aWorkerPrivate == GetWorkerPrivateFromContext(aCx)); MOZ_ASSERT(aWorkerPrivate->GlobalScope()); @@ -124,4 +109,97 @@ void MessageEventRunnable::DispatchError(JSContext* aCx, aTarget->DispatchEvent(*event); } +MessageEventToParentRunnable::MessageEventToParentRunnable( + WorkerPrivate* aWorkerPrivate) + : WorkerParentDebuggeeRunnable("MessageEventToParentRunnable"), + StructuredCloneHolder(CloningSupported, TransferringSupported, + StructuredCloneScope::SameProcess) {} + +bool MessageEventToParentRunnable::DispatchDOMEvent( + JSContext* aCx, WorkerPrivate* aWorkerPrivate, + DOMEventTargetHelper* aTarget, bool aIsMainThread) { + nsCOMPtr<nsIGlobalObject> parent = aTarget->GetParentObject(); + + // For some workers without window, parent is null and we try to find it + // from the JS Context. + if (!parent) { + JS::Rooted<JSObject*> globalObject(aCx, JS::CurrentGlobalOrNull(aCx)); + if (NS_WARN_IF(!globalObject)) { + return false; + } + + parent = xpc::NativeGlobal(globalObject); + if (NS_WARN_IF(!parent)) { + return false; + } + } + + MOZ_ASSERT(parent); + + JS::Rooted<JS::Value> messageData(aCx); + IgnoredErrorResult rv; + + JS::CloneDataPolicy cloneDataPolicy; + if (parent->GetClientInfo().isSome() && + parent->GetClientInfo()->AgentClusterId().isSome() && + parent->GetClientInfo()->AgentClusterId()->Equals( + aWorkerPrivate->AgentClusterId())) { + cloneDataPolicy.allowIntraClusterClonableSharedObjects(); + } + + if (aWorkerPrivate->IsSharedMemoryAllowed()) { + cloneDataPolicy.allowSharedMemoryObjects(); + } + + Read(parent, aCx, &messageData, cloneDataPolicy, rv); + + if (NS_WARN_IF(rv.Failed())) { + DispatchError(aCx, aTarget); + return false; + } + + Sequence<OwningNonNull<MessagePort>> ports; + if (!TakeTransferredPortsAsSequence(ports)) { + DispatchError(aCx, aTarget); + return false; + } + + RefPtr<MessageEvent> event = new MessageEvent(aTarget, nullptr, nullptr); + event->InitMessageEvent(nullptr, u"message"_ns, CanBubble::eNo, + Cancelable::eNo, messageData, u""_ns, u""_ns, nullptr, + ports); + + event->SetTrusted(true); + + aTarget->DispatchEvent(*event); + + return true; +} + +bool MessageEventToParentRunnable::WorkerRun(JSContext* aCx, + WorkerPrivate* aWorkerPrivate) { + if (!aWorkerPrivate->IsAcceptingEvents()) { + return true; + } + + aWorkerPrivate->AssertInnerWindowIsCorrect(); + + return DispatchDOMEvent(aCx, aWorkerPrivate, + aWorkerPrivate->ParentEventTargetRef(), + !aWorkerPrivate->GetParent()); +} + +void MessageEventToParentRunnable::DispatchError( + JSContext* aCx, DOMEventTargetHelper* aTarget) { + RootedDictionary<MessageEventInit> init(aCx); + init.mBubbles = false; + init.mCancelable = false; + + RefPtr<Event> event = + MessageEvent::Constructor(aTarget, u"messageerror"_ns, init); + event->SetTrusted(true); + + aTarget->DispatchEvent(*event); +} + } // namespace mozilla::dom |