Bug 1313004 - ServiceWorkerMessageEvent can be generated code, r=qdot

This commit is contained in:
Andrea Marchesini 2016-10-26 22:00:17 +02:00
parent 0a299d9f15
commit 92035ed242
15 changed files with 49 additions and 296 deletions

View File

@ -144,14 +144,15 @@ PostMessageEvent::Run()
Nullable<WindowProxyOrMessagePort> source;
source.SetValue().SetAsWindowProxy() = mSource ? mSource->AsOuter() : nullptr;
Sequence<OwningNonNull<MessagePort>> ports;
if (!TakeTransferredPortsAsSequence(ports)) {
return NS_ERROR_OUT_OF_MEMORY;
}
event->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"),
false /*non-bubbling */, false /*cancelable */,
messageData, mCallerOrigin,
EmptyString(), source,
Sequence<OwningNonNull<MessagePort>>());
nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
event->SetPorts(Move(ports));
EmptyString(), source, ports);
// We can't simply call dispatchEvent on the window because doing so ends
// up flipping the trusted bit on the event, and we don't want that to

View File

@ -1279,5 +1279,20 @@ StructuredCloneHolder::CustomFreeTransferHandler(uint32_t aTag,
}
}
bool
StructuredCloneHolder::TakeTransferredPortsAsSequence(Sequence<OwningNonNull<mozilla::dom::MessagePort>>& aPorts)
{
nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
aPorts.Clear();
for (uint32_t i = 0, len = ports.Length(); i < len; ++i) {
if (!aPorts.AppendElement(ports[i].forget(), fallible)) {
return false;
}
}
return true;
}
} // dom namespace
} // mozilla namespace

View File

@ -9,6 +9,7 @@
#include "js/StructuredClone.h"
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsISupports.h"
#include "nsTArray.h"
@ -207,6 +208,11 @@ public:
return Move(mTransferredPorts);
}
// This method uses TakeTransferredPorts() to populate a sequence of
// MessagePorts for WebIDL binding classes.
bool
TakeTransferredPortsAsSequence(Sequence<OwningNonNull<mozilla::dom::MessagePort>>& aPorts);
nsTArray<MessagePortIdentifier>& PortIdentifiers() const
{
MOZ_ASSERT(mSupportsTransferring);

View File

@ -175,13 +175,6 @@ MessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
aPorts = mPorts;
}
void
MessageEvent::SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts)
{
MOZ_ASSERT(mPorts.IsEmpty());
mPorts = Move(aPorts);
}
void
MessageEvent::SetSource(mozilla::dom::MessagePort* aPort)
{

View File

@ -49,8 +49,6 @@ public:
void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
void SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts);
// Non WebIDL methods
void SetSource(mozilla::dom::MessagePort* aPort);

View File

@ -134,17 +134,18 @@ private:
RefPtr<MessageEvent> event =
new MessageEvent(eventTarget, nullptr, nullptr);
Sequence<OwningNonNull<MessagePort>> ports;
if (!mData->TakeTransferredPortsAsSequence(ports)) {
return NS_ERROR_OUT_OF_MEMORY;
}
event->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"),
false /* non-bubbling */,
false /* cancelable */, value, EmptyString(),
EmptyString(), nullptr,
Sequence<OwningNonNull<MessagePort>>());
EmptyString(), nullptr, ports);
event->SetTrusted(true);
event->SetSource(mPort);
nsTArray<RefPtr<MessagePort>> ports = mData->TakeTransferredPorts();
event->SetPorts(Move(ports));
bool dummy;
mPort->DispatchEvent(static_cast<dom::Event*>(event.get()), &dummy);

View File

@ -15,7 +15,6 @@ interface ServiceWorkerMessageEvent : Event {
/**
* Custom data associated with this event.
*/
[GetterThrows]
readonly attribute any data;
/**

View File

@ -410,7 +410,6 @@ WEBIDL_FILES = [
'ServiceWorker.webidl',
'ServiceWorkerContainer.webidl',
'ServiceWorkerGlobalScope.webidl',
'ServiceWorkerMessageEvent.webidl',
'ServiceWorkerRegistration.webidl',
'SettingChangeNotification.webidl',
'SettingsManager.webidl',
@ -771,6 +770,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'ProgressEvent.webidl',
'RecordErrorEvent.webidl',
'ScrollViewChangeEvent.webidl',
'ServiceWorkerMessageEvent.webidl',
'StyleRuleChangeEvent.webidl',
'StyleSheetApplicableStateChangeEvent.webidl',
'StyleSheetChangeEvent.webidl',

View File

@ -165,12 +165,14 @@ private:
init.mSource.SetValue().SetAsServiceWorker() = serviceWorker;
}
if (!TakeTransferredPortsAsSequence(init.mPorts)) {
return NS_ERROR_OUT_OF_MEMORY;
}
RefPtr<ServiceWorkerMessageEvent> event =
ServiceWorkerMessageEvent::Constructor(aTargetContainer,
NS_LITERAL_STRING("message"), init, rv);
nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
event->SetPorts(Move(ports));
NS_LITERAL_STRING("message"),
init);
event->SetTrusted(true);
bool status = false;

View File

@ -1252,13 +1252,6 @@ ExtendableMessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
aPorts = mPorts;
}
void
ExtendableMessageEvent::SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts)
{
MOZ_ASSERT(mPorts.IsEmpty());
mPorts = Move(aPorts);
}
void
ExtendableMessageEvent::SetSource(ServiceWorkerClient* aClient)
{

View File

@ -309,8 +309,6 @@ public:
void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
void SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts);
void SetSource(ServiceWorkerClient* aClient);
void SetSource(ServiceWorker* aServiceWorker);

View File

@ -1,166 +0,0 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ServiceWorkerMessageEvent.h"
#include "mozilla/dom/ServiceWorkerMessageEventBinding.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/MessagePortBinding.h"
#include "mozilla/HoldDropJSObjects.h"
#include "jsapi.h"
#include "ServiceWorker.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(ServiceWorkerMessageEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServiceWorkerMessageEvent, Event)
tmp->mData.setUndefined();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mServiceWorker)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessagePort)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPorts)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServiceWorkerMessageEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorker)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagePort)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPorts)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServiceWorkerMessageEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerMessageEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NS_IMPL_ADDREF_INHERITED(ServiceWorkerMessageEvent, Event)
NS_IMPL_RELEASE_INHERITED(ServiceWorkerMessageEvent, Event)
ServiceWorkerMessageEvent::ServiceWorkerMessageEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent)
: Event(aOwner, aPresContext, aEvent)
, mData(JS::UndefinedValue())
{
mozilla::HoldJSObjects(this);
}
ServiceWorkerMessageEvent::~ServiceWorkerMessageEvent()
{
mData.setUndefined();
DropJSObjects(this);
}
JSObject*
ServiceWorkerMessageEvent::WrapObjectInternal(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return mozilla::dom::ServiceWorkerMessageEventBinding::Wrap(aCx, this, aGivenProto);
}
void
ServiceWorkerMessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
ErrorResult& aRv) const
{
aData.set(mData);
if (!JS_WrapValue(aCx, aData)) {
aRv.Throw(NS_ERROR_FAILURE);
}
}
void
ServiceWorkerMessageEvent::GetOrigin(nsAString& aOrigin) const
{
aOrigin = mOrigin;
}
void
ServiceWorkerMessageEvent::GetLastEventId(nsAString& aLastEventId) const
{
aLastEventId = mLastEventId;
}
void
ServiceWorkerMessageEvent::GetSource(Nullable<OwningServiceWorkerOrMessagePort>& aValue) const
{
if (mServiceWorker) {
aValue.SetValue().SetAsServiceWorker() = mServiceWorker;
} else if (mMessagePort) {
aValue.SetValue().SetAsMessagePort() = mMessagePort;
}
}
void
ServiceWorkerMessageEvent::SetSource(mozilla::dom::MessagePort* aPort)
{
mMessagePort = aPort;
}
void
ServiceWorkerMessageEvent::SetSource(workers::ServiceWorker* aServiceWorker)
{
mServiceWorker = aServiceWorker;
}
void
ServiceWorkerMessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
{
aPorts = mPorts;
}
void
ServiceWorkerMessageEvent::SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts)
{
MOZ_ASSERT(mPorts.IsEmpty());
mPorts = Move(aPorts);
}
/* static */ already_AddRefed<ServiceWorkerMessageEvent>
ServiceWorkerMessageEvent::Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const ServiceWorkerMessageEventInit& aParam,
ErrorResult& aRv)
{
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
return Constructor(t, aType, aParam, aRv);
}
/* static */ already_AddRefed<ServiceWorkerMessageEvent>
ServiceWorkerMessageEvent::Constructor(EventTarget* aEventTarget,
const nsAString& aType,
const ServiceWorkerMessageEventInit& aParam,
ErrorResult& aRv)
{
RefPtr<ServiceWorkerMessageEvent> event =
new ServiceWorkerMessageEvent(aEventTarget, nullptr, nullptr);
event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
bool trusted = event->Init(aEventTarget);
event->SetTrusted(trusted);
event->mData = aParam.mData;
event->mOrigin = aParam.mOrigin;
event->mLastEventId = aParam.mLastEventId;
if (!aParam.mSource.IsNull()) {
if (aParam.mSource.Value().IsServiceWorker()) {
event->mServiceWorker = aParam.mSource.Value().GetAsServiceWorker();
} else if (aParam.mSource.Value().IsMessagePort()) {
event->mMessagePort = aParam.mSource.Value().GetAsMessagePort();
}
}
event->mPorts.AppendElements(aParam.mPorts);
return event.forget();
}
} // namespace dom
} // namespace mozilla

View File

@ -1,85 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_serviceworkermessageevent_h__
#define mozilla_dom_serviceworkermessageevent_h__
#include "mozilla/dom/Event.h"
namespace mozilla {
namespace dom {
struct ServiceWorkerMessageEventInit;
class MessagePort;
class OwningServiceWorkerOrMessagePort;
namespace workers {
class ServiceWorker;
}
class ServiceWorkerMessageEvent final : public Event
{
public:
ServiceWorkerMessageEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ServiceWorkerMessageEvent, Event)
// Forward to base class
NS_FORWARD_TO_EVENT
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
ErrorResult& aRv) const;
void GetOrigin(nsAString& aOrigin) const;
void GetLastEventId(nsAString& aLastEventId) const;
void GetSource(Nullable<OwningServiceWorkerOrMessagePort>& aValue) const;
void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
void SetSource(mozilla::dom::MessagePort* aPort);
void SetSource(workers::ServiceWorker* aServiceWorker);
void SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts);
static already_AddRefed<ServiceWorkerMessageEvent>
Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const ServiceWorkerMessageEventInit& aEventInit,
ErrorResult& aRv);
static already_AddRefed<ServiceWorkerMessageEvent>
Constructor(EventTarget* aEventTarget,
const nsAString& aType,
const ServiceWorkerMessageEventInit& aEventInit,
ErrorResult& aRv);
protected:
~ServiceWorkerMessageEvent();
private:
JS::Heap<JS::Value> mData;
nsString mOrigin;
nsString mLastEventId;
RefPtr<workers::ServiceWorker> mServiceWorker;
RefPtr<MessagePort> mMessagePort;
nsTArray<RefPtr<MessagePort>> mPorts;
};
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_workers_serviceworkermessageevent_h__ */

View File

@ -683,7 +683,10 @@ public:
return false;
}
nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
Sequence<OwningNonNull<MessagePort>> ports;
if (!TakeTransferredPortsAsSequence(ports)) {
return false;
}
nsCOMPtr<nsIDOMEvent> domEvent;
RefPtr<ExtendableMessageEvent> extendableEvent;
@ -699,6 +702,7 @@ public:
init.mCancelable = false;
init.mData = messageData;
init.mPorts = ports;
ErrorResult rv;
extendableEvent = ExtendableMessageEvent::Constructor(
@ -708,7 +712,6 @@ public:
return false;
}
extendableEvent->SetSource(client);
extendableEvent->SetPorts(Move(ports));
domEvent = do_QueryObject(extendableEvent);
} else {
@ -721,8 +724,7 @@ public:
EmptyString(),
EmptyString(),
nullptr,
Sequence<OwningNonNull<MessagePort>>());
event->SetPorts(Move(ports));
ports);
domEvent = do_QueryObject(event);
}
@ -6489,6 +6491,9 @@ WorkerPrivate::ConnectMessagePort(JSContext* aCx,
init.mBubbles = false;
init.mCancelable = false;
init.mSource.SetValue().SetAsMessagePort() = port;
if (!init.mPorts.AppendElement(port.forget(), fallible)) {
return false;
}
RefPtr<MessageEvent> event =
MessageEvent::Constructor(globalObject,
@ -6496,11 +6501,6 @@ WorkerPrivate::ConnectMessagePort(JSContext* aCx,
event->SetTrusted(true);
nsTArray<RefPtr<MessagePort>> ports;
ports.AppendElement(port);
event->SetPorts(Move(ports));
nsCOMPtr<nsIDOMEvent> domEvent = do_QueryObject(event);
nsEventStatus dummy = nsEventStatus_eIgnore;

View File

@ -10,7 +10,6 @@ EXPORTS.mozilla.dom += [
'ServiceWorkerCommon.h',
'ServiceWorkerContainer.h',
'ServiceWorkerEvents.h',
'ServiceWorkerMessageEvent.h',
'ServiceWorkerRegistrar.h',
'ServiceWorkerRegistration.h',
'WorkerLocation.h',
@ -66,7 +65,6 @@ UNIFIED_SOURCES += [
'ServiceWorkerManagerChild.cpp',
'ServiceWorkerManagerParent.cpp',
'ServiceWorkerManagerService.cpp',
'ServiceWorkerMessageEvent.cpp',
'ServiceWorkerPrivate.cpp',
'ServiceWorkerRegisterJob.cpp',
'ServiceWorkerRegistrar.cpp',