Bug 888600 - Move ContentFrameMessageManager to WebIDL. Part 4: Convert MessageManager to WebIDL. r=bz.

--HG--
extra : rebase_source : 9d34380827193c597b2754e290aa5636b75f7461
This commit is contained in:
Peter Van der Beken 2017-06-20 11:09:50 +02:00
parent f24f511032
commit 8c4cf977e2
20 changed files with 1054 additions and 322 deletions

View File

@ -8,6 +8,7 @@
#define mozilla_dom_ChildProcessMessageManager_h
#include "mozilla/dom/SyncMessageSender.h"
#include "mozilla/dom/MessageManagerBinding.h"
namespace mozilla {
namespace dom {
@ -23,6 +24,11 @@ public:
mozilla::HoldJSObjects(this);
}
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{
return ChildProcessMessageManagerBinding::Wrap(aCx, this, aGivenProto);
}
protected:
virtual ~ChildProcessMessageManager()
{

View File

@ -5,7 +5,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ChromeMessageBroadcaster.h"
#include "AccessCheck.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/dom/MessageManagerBinding.h"
namespace mozilla {
namespace dom {
@ -32,5 +34,14 @@ ChromeMessageBroadcaster::~ChromeMessageBroadcaster()
}
}
JSObject*
ChromeMessageBroadcaster::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
MOZ_ASSERT(nsContentUtils::IsSystemCaller(aCx));
return ChromeMessageBroadcasterBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace dom
} // namespace mozilla

View File

@ -26,6 +26,63 @@ public:
: ChromeMessageBroadcaster(aParentManager, MessageManagerFlags::MM_NONE)
{}
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
using nsFrameMessageManager::BroadcastAsyncMessage;
void BroadcastAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
mozilla::ErrorResult& aError)
{
DispatchAsyncMessage(aCx, aMessageName, aObj, aObjects, nullptr,
JS::UndefinedHandleValue, aError);
}
uint32_t ChildCount()
{
return mChildManagers.Length();
}
using nsFrameMessageManager::GetChildAt;
MessageListenerManager* GetChildAt(uint32_t aIndex)
{
return mChildManagers.SafeElementAt(aIndex);
}
// XPCOM ReleaseCachedProcesses is OK
// ProcessScriptLoader
using nsFrameMessageManager::LoadProcessScript;
void LoadProcessScript(const nsAString& aUrl, bool aAllowDelayedLoad,
mozilla::ErrorResult& aError)
{
LoadScript(aUrl, aAllowDelayedLoad, false, aError);
}
// XPCOM RemoveDelayedProcessScript is OK
using nsFrameMessageManager::GetDelayedProcessScripts;
void GetDelayedProcessScripts(JSContext* aCx,
nsTArray<nsTArray<JS::Value>>& aScripts,
mozilla::ErrorResult& aError)
{
GetDelayedScripts(aCx, aScripts, aError);
}
// GlobalProcessScriptLoader
// XPCOM GetInitialProcessData is OK
// FrameScriptLoader
using nsFrameMessageManager::LoadFrameScript;
void LoadFrameScript(const nsAString& aUrl, bool aAllowDelayedLoad,
bool aRunInGlobalScope, mozilla::ErrorResult& aError)
{
LoadScript(aUrl, aAllowDelayedLoad, aRunInGlobalScope, aError);
}
using nsFrameMessageManager::GetDelayedFrameScripts;
void GetDelayedFrameScripts(JSContext* aCx,
nsTArray<nsTArray<JS::Value>>& aScripts,
mozilla::ErrorResult& aError)
{
GetDelayedScripts(aCx, aScripts, aError);
}
private:
ChromeMessageBroadcaster(nsFrameMessageManager* aParentManager,
MessageManagerFlags aFlags);

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ChromeMessageSender.h"
#include "mozilla/dom/MessageManagerBinding.h"
namespace mozilla {
namespace dom {
@ -27,5 +28,14 @@ ChromeMessageSender::ChromeMessageSender(ipc::MessageManagerCallback* aCallback,
}
}
JSObject*
ChromeMessageSender::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
MOZ_ASSERT(nsContentUtils::IsSystemCaller(aCx));
return ChromeMessageSenderBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace dom
} // namespace mozilla

View File

@ -18,6 +18,40 @@ public:
ChromeMessageSender(ipc::MessageManagerCallback* aCallback,
nsFrameMessageManager* aParentManager,
MessageManagerFlags aFlags=MessageManagerFlags::MM_NONE);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// ProcessScriptLoader
using nsFrameMessageManager::LoadProcessScript;
void LoadProcessScript(const nsAString& aUrl, bool aAllowDelayedLoad,
mozilla::ErrorResult& aError)
{
LoadScript(aUrl, aAllowDelayedLoad, false, aError);
}
// XPCOM RemoveDelayedProcessScript is OK
using nsFrameMessageManager::GetDelayedProcessScripts;
void GetDelayedProcessScripts(JSContext* aCx,
nsTArray<nsTArray<JS::Value>>& aScripts,
mozilla::ErrorResult& aError)
{
GetDelayedScripts(aCx, aScripts, aError);
}
// FrameScriptLoader
using nsFrameMessageManager::LoadFrameScript;
void LoadFrameScript(const nsAString& aUrl, bool aAllowDelayedLoad,
bool aRunInGlobalScope, mozilla::ErrorResult& aError)
{
LoadScript(aUrl, aAllowDelayedLoad, aRunInGlobalScope, aError);
}
using nsFrameMessageManager::GetDelayedFrameScripts;
void GetDelayedFrameScripts(JSContext* aCx,
nsTArray<nsTArray<JS::Value>>& aScripts,
mozilla::ErrorResult& aError)
{
GetDelayedScripts(aCx, aScripts, aError);
}
};
} // namespace dom

View File

@ -22,6 +22,7 @@ MessageListenerManager::~MessageListenerManager()
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageListenerManager)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_END_INHERITING(nsFrameMessageManager)
NS_IMPL_ADDREF_INHERITED(MessageListenerManager, nsFrameMessageManager)
NS_IMPL_RELEASE_INHERITED(MessageListenerManager, nsFrameMessageManager)
@ -31,8 +32,13 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MessageListenerManager,
nsFrameMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MessageListenerManager,
nsFrameMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MessageListenerManager,
nsFrameMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

View File

@ -9,16 +9,23 @@
#include "nsCycleCollectionNoteChild.h"
#include "nsFrameMessageManager.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class MessageListenerManager : public nsFrameMessageManager
class MessageListenerManager : public nsFrameMessageManager,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessageListenerManager,
nsFrameMessageManager)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MessageListenerManager,
nsFrameMessageManager)
nsISupports* GetParentObject()
{
return ToSupports(mParentManager.get());
}
virtual nsFrameMessageManager* GetParentManager() override
{

View File

@ -178,11 +178,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS |
XPC_SCRIPTABLE_WANT_ENUMERATE |
XPC_SCRIPTABLE_IS_GLOBAL_OBJECT)
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -440,21 +435,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIContentProcessMessageManager)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageBroadcaster, nsISupports)
DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
DOM_CLASSINFO_MAP_ENTRY(nsIProcessScriptLoader)
DOM_CLASSINFO_MAP_ENTRY(nsIGlobalProcessScriptLoader)
DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
DOM_CLASSINFO_MAP_ENTRY(nsIMessageBroadcaster)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageSender, nsISupports)
DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
DOM_CLASSINFO_MAP_ENTRY(nsIProcessScriptLoader)
DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControlElement, nsIDOMXULControlElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULControlElement)
DOM_CLASSINFO_MAP_END

View File

@ -21,8 +21,6 @@ enum nsDOMClassInfoID
eDOMClassInfo_ContentFrameMessageManager_id,
eDOMClassInfo_ContentProcessMessageManager_id,
eDOMClassInfo_ChromeMessageBroadcaster_id,
eDOMClassInfo_ChromeMessageSender_id,
eDOMClassInfo_XULControlElement_id,
eDOMClassInfo_XULLabeledControlElement_id,

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
#include "js/RootingAPI.h"
#include "nsTObserverArray.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/dom/CallbackObject.h"
#include "mozilla/dom/SameProcessMessageQueue.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/jsipc/CpowHolder.h"
@ -43,7 +44,10 @@ class nsIContentChild;
class ChildProcessMessageManager;
class ChromeMessageSender;
class ClonedMessageData;
class MessageListener;
class MessageListenerManager;
class MessageManagerReporter;
template<typename T> class Optional;
namespace ipc {
@ -122,6 +126,10 @@ void UnpackClonedMessageDataForChild(const ClonedMessageData& aClonedData,
StructuredCloneData& aData);
} // namespace ipc
typedef CallbackObjectHolder<mozilla::dom::MessageListener,
nsIMessageListener> MessageListenerHolder;
} // namespace dom
} // namespace mozilla
@ -132,12 +140,22 @@ struct nsMessageListenerInfo
return &aOther == this;
}
// Exactly one of mStrongListener and mWeakListener must be non-null.
nsCOMPtr<nsIMessageListener> mStrongListener;
// If mWeakListener is null then mStrongListener holds either a MessageListener or an
// nsIMessageListener. If mWeakListener is non-null then mStrongListener contains null.
mozilla::dom::MessageListenerHolder mStrongListener;
nsWeakPtr mWeakListener;
bool mListenWhenClosed;
};
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
nsMessageListenerInfo& aField,
const char* aName,
uint32_t aFlags = 0)
{
ImplCycleCollectionTraverse(aCallback, aField.mStrongListener, aName, aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mWeakListener, aName, aFlags);
}
class MOZ_STACK_CLASS SameProcessCpowHolder : public mozilla::jsipc::CpowHolder
{
@ -178,6 +196,62 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFrameMessageManager,
nsIContentFrameMessageManager)
// MessageListenerManager
void AddMessageListener(const nsAString& aMessageName,
mozilla::dom::MessageListener& aListener,
bool aListenWhenClosed,
mozilla::ErrorResult& aError);
void RemoveMessageListener(const nsAString& aMessageName,
mozilla::dom::MessageListener& aListener,
mozilla::ErrorResult& aError);
void AddWeakMessageListener(const nsAString& aMessageName,
mozilla::dom::MessageListener& aListener,
mozilla::ErrorResult& aError);
void RemoveWeakMessageListener(const nsAString& aMessageName,
mozilla::dom::MessageListener& aListener,
mozilla::ErrorResult& aError);
// MessageSender
void SendAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
JS::Handle<JS::Value> aTransfers,
mozilla::ErrorResult& aError)
{
DispatchAsyncMessage(aCx, aMessageName, aObj, aObjects, aPrincipal, aTransfers,
aError);
}
already_AddRefed<nsIMessageSender>
GetProcessMessageManager(mozilla::ErrorResult& aError);
void GetRemoteType(nsAString& aRemoteType, mozilla::ErrorResult& aError) const;
// SyncMessageSender
void SendSyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
nsTArray<JS::Value>& aResult,
mozilla::ErrorResult& aError)
{
SendMessage(aCx, aMessageName, aObj, aObjects, aPrincipal, true, aResult, aError);
}
void SendRpcMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
nsTArray<JS::Value>& aResult,
mozilla::ErrorResult& aError)
{
SendMessage(aCx, aMessageName, aObj, aObjects, aPrincipal, false, aResult, aError);
}
// GlobalProcessScriptLoader
void GetInitialProcessData(JSContext* aCx,
JS::MutableHandle<JS::Value> aInitialProcessData,
mozilla::ErrorResult& aError);
NS_DECL_NSIMESSAGELISTENERMANAGER
NS_DECL_NSIMESSAGESENDER
NS_DECL_NSIMESSAGEBROADCASTER
@ -197,11 +271,8 @@ public:
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal);
void AddChildManager(nsFrameMessageManager* aManager);
void RemoveChildManager(nsFrameMessageManager* aManager)
{
mChildManagers.RemoveObject(aManager);
}
void AddChildManager(mozilla::dom::MessageListenerManager* aManager);
void RemoveChildManager(mozilla::dom::MessageListenerManager* aManager);
void Disconnect(bool aRemoveFromParent = true);
void Close();
@ -245,7 +316,9 @@ public:
void LoadPendingScripts();
private:
protected:
friend class MMListenerRemover;
virtual nsFrameMessageManager* GetParentManager()
{
return nullptr;
@ -254,6 +327,13 @@ private:
{
}
void DispatchAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
JS::Handle<JS::Value> aTransfers,
mozilla::ErrorResult& aError);
nsresult SendMessage(const nsAString& aMessageName,
JS::Handle<JS::Value> aJSON,
JS::Handle<JS::Value> aObjects,
@ -262,6 +342,14 @@ private:
uint8_t aArgc,
JS::MutableHandle<JS::Value> aRetval,
bool aIsSync);
void SendMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj, JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal, bool aIsSync, nsTArray<JS::Value>& aResult,
mozilla::ErrorResult& aError);
void SendMessage(JSContext* aCx, const nsAString& aMessageName,
StructuredCloneData& aData, JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal, bool aIsSync,
nsTArray<JS::Value>& aResult, mozilla::ErrorResult& aError);
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
bool aTargetClosed, const nsAString& aMessage,
@ -269,19 +357,28 @@ private:
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal);
NS_IMETHOD LoadScript(const nsAString& aURL,
bool aAllowDelayedLoad,
bool aRunInGlobalScope);
NS_IMETHOD RemoveDelayedScript(const nsAString& aURL);
NS_IMETHOD GetDelayedScripts(JSContext* aCx, JS::MutableHandle<JS::Value> aList);
void LoadScript(const nsAString& aURL, bool aAllowDelayedLoad,
bool aRunInGlobalScope, mozilla::ErrorResult& aError);
void RemoveDelayedScript(const nsAString& aURL);
nsresult GetDelayedScripts(JSContext* aCx,
JS::MutableHandle<JS::Value> aList);
void GetDelayedScripts(JSContext* aCx, nsTArray<nsTArray<JS::Value>>& aList,
mozilla::ErrorResult& aError);
enum ProcessCheckerType {
PROCESS_CHECKER_PERMISSION,
PROCESS_CHECKER_MANIFEST_URL,
ASSERT_APP_HAS_PERMISSION
};
bool AssertProcessInternal(ProcessCheckerType aType,
const nsAString& aCapability,
mozilla::ErrorResult& aError);
protected:
friend class MMListenerRemover;
// We keep the message listeners as arrays in a hastable indexed by the
// message name. That gives us fast lookups in ReceiveMessage().
nsClassHashtable<nsStringHashKey,
nsAutoTObserverArray<nsMessageListenerInfo, 1>> mListeners;
nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
nsTArray<RefPtr<mozilla::dom::MessageListenerManager>> mChildManagers;
bool mChrome; // true if we're in the chrome process
bool mGlobal; // true if we're the global frame message manager
bool mIsProcessManager; // true if the message manager belongs to the process realm
@ -303,15 +400,13 @@ public:
static nsFrameMessageManager* sSameProcessParentManager;
static nsTArray<nsCOMPtr<nsIRunnable> >* sPendingSameProcessAsyncMessages;
private:
void AddMessageListener(const nsAString& aMessageName,
mozilla::dom::MessageListenerHolder&& aListener,
bool aListenWhenClosed);
void RemoveMessageListener(const nsAString& aMessageName,
const mozilla::dom::MessageListenerHolder& aListener);
static mozilla::dom::ChildProcessMessageManager* sChildProcessManager;
enum ProcessCheckerType {
PROCESS_CHECKER_PERMISSION,
PROCESS_CHECKER_MANIFEST_URL,
ASSERT_APP_HAS_PERMISSION
};
nsresult AssertProcessInternal(ProcessCheckerType aType,
const nsAString& aCapability,
bool* aValid);
};
/* A helper class for taking care of many details for async message sending

View File

@ -570,6 +570,18 @@ DOMInterfaces = {
'headerFile': 'MediaRecorder.h',
},
'MessageBroadcaster': {
'concrete': False
},
'MessageListenerManager': {
'concrete': False
},
'MessageSender': {
'concrete': False
},
'MimeType': {
'headerFile' : 'nsMimeTypeArray.h',
'nativeType': 'nsMimeType',
@ -1015,6 +1027,10 @@ DOMInterfaces = {
'concrete': False,
},
'SyncMessageSender' : {
'concrete': False,
},
'TestFunctions': {
'wrapperCache': False
},
@ -1714,10 +1730,6 @@ addExternalIface('nsIBrowserDOMWindow', nativeType='nsIBrowserDOMWindow',
addExternalIface('nsIFile', nativeType='nsIFile', notflattened=True)
addExternalIface('nsILoadGroup', nativeType='nsILoadGroup',
headerFile='nsILoadGroup.h', notflattened=True)
addExternalIface('nsIMessageBroadcaster', nativeType='nsIMessageBroadcaster',
headerFile='nsIMessageManager.h', notflattened=True)
addExternalIface('nsIMessageSender', nativeType='nsIMessageSender',
headerFile='nsIMessageManager.h', notflattened=True)
addExternalIface('nsIPrintSettings', nativeType='nsIPrintSettings',
notflattened=True)
addExternalIface('nsISelectionListener', nativeType='nsISelectionListener')

View File

@ -1107,7 +1107,7 @@ class CGHeaders(CGWrapper):
interfacesImplementingSelf)
# Grab the includes for the things that involve XPCOM interfaces
hasInstanceIncludes = set("nsIDOM" + d.interface.identifier.name + ".h" for d
hasInstanceIncludes = set(self.getDeclarationFilename(d.interface) for d
in descriptors if
d.interface.hasInterfaceObject() and
NeedsGeneratedHasInstance(d) and

View File

@ -233,6 +233,13 @@ ToJSValue(JSContext* aCx,
// Accept existing JS values (which may not be same-compartment with us
MOZ_MUST_USE inline bool
ToJSValue(JSContext* aCx, const JS::Value& aArgument,
JS::MutableHandle<JS::Value> aValue)
{
aValue.set(aArgument);
return MaybeWrapValue(aCx, aValue);
}
MOZ_MUST_USE inline bool
ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
JS::MutableHandle<JS::Value> aValue)
{
@ -312,33 +319,13 @@ ToJSValue(JSContext* aCx,
Promise& aArgument,
JS::MutableHandle<JS::Value> aValue);
// Accept arrays of other things we accept
// Accept arrays (and nested arrays) of other things we accept
template <typename T>
MOZ_MUST_USE bool
ToJSValue(JSContext* aCx,
T* aArguments,
size_t aLength,
JS::MutableHandle<JS::Value> aValue)
{
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
JS::AutoValueVector v(aCx);
if (!v.resize(aLength)) {
return false;
}
for (size_t i = 0; i < aLength; ++i) {
if (!ToJSValue(aCx, aArguments[i], v[i])) {
return false;
}
}
JSObject* arrayObj = JS_NewArrayObject(aCx, v);
if (!arrayObj) {
return false;
}
aValue.setObject(*arrayObj);
return true;
}
JS::MutableHandle<JS::Value> aValue);
template <typename T>
MOZ_MUST_USE bool
@ -369,6 +356,34 @@ ToJSValue(JSContext* aCx,
return ToJSValue(aCx, aArgument, N, aValue);
}
// Accept arrays of other things we accept
template <typename T>
MOZ_MUST_USE bool
ToJSValue(JSContext* aCx,
T* aArguments,
size_t aLength,
JS::MutableHandle<JS::Value> aValue)
{
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
JS::AutoValueVector v(aCx);
if (!v.resize(aLength)) {
return false;
}
for (size_t i = 0; i < aLength; ++i) {
if (!ToJSValue(aCx, aArguments[i], v[i])) {
return false;
}
}
JSObject* arrayObj = JS_NewArrayObject(aCx, v);
if (!arrayObj) {
return false;
}
aValue.setObject(*arrayObj);
return true;
}
} // namespace dom
} // namespace mozilla

View File

@ -8,7 +8,6 @@ interface LoadContext;
interface TabParent;
interface URI;
interface nsIDocShell;
interface nsIMessageSender;
interface nsIPrintSettings;
interface nsIWebBrowserPersistDocumentReceiver;
interface nsIWebProgressListener;
@ -104,7 +103,7 @@ interface FrameLoader {
void activateFrameEvent(DOMString aType, boolean capture);
// Note, when frameloaders are swapped, also messageManagers are swapped.
readonly attribute nsIMessageSender? messageManager;
readonly attribute MessageSender? messageManager;
/**
* Request that the next time a remote layer transaction has been

View File

@ -22,6 +22,9 @@ Attr implements LegacyQueryInterface;
BarProp implements LegacyQueryInterface;
BoxObject implements LegacyQueryInterface;
CaretPosition implements LegacyQueryInterface;
ChildProcessMessageManager implements LegacyQueryInterface;
ChromeMessageBroadcaster implements LegacyQueryInterface;
ChromeMessageSender implements LegacyQueryInterface;
Comment implements LegacyQueryInterface;
Crypto implements LegacyQueryInterface;
CSSMozDocumentRule implements LegacyQueryInterface;

View File

@ -0,0 +1,311 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
interface MozFrameLoader;
interface Principal;
dictionary ReceiveMessageArgument
{
/**
* The target of the message. Either an element owning the message manager, or message
* manager itself if no element owns it.
*/
required nsISupports target;
/**
* Message name.
*/
required DOMString name;
required boolean sync;
/**
* Structured clone of the sent message data
*/
any data = null;
/**
* Same as .data, deprecated.
*/
any json = null;
/**
* Named table of jsvals/objects, or null.
*/
required object objects;
sequence<MessagePort> ports;
/**
* Principal for the window app.
*/
required Principal? principal;
MozFrameLoader targetFrameLoader;
};
callback interface MessageListener
{
/**
* Each listener is invoked with its own copy of the message
* parameter.
*
* When the listener is called, 'this' value is the target of the message.
*
* If the message is synchronous, the possible return value is
* returned as JSON (will be changed to use structured clones).
* When there are multiple listeners to sync messages, each
* listener's return value is sent back as an array. |undefined|
* return values show up as undefined values in the array.
*/
any receiveMessage(optional ReceiveMessageArgument argument);
};
[ChromeOnly]
interface MessageListenerManager
{
/**
* Register |listener| to receive |messageName|. All listener
* callbacks for a particular message are invoked when that message
* is received.
*
* The message manager holds a strong ref to |listener|.
*
* If the same listener registers twice for the same message, the
* second registration is ignored.
*
* Pass true for listenWhenClosed if you want to receive messages
* during the short period after a frame has been removed from the
* DOM and before its frame script has finished unloading. This
* parameter only has an effect for frame message managers in
* the main process. Default is false.
*/
[Throws]
void addMessageListener(DOMString messageName,
MessageListener listener,
optional boolean listenWhenClosed = false);
/**
* Undo an |addMessageListener| call -- that is, calling this causes us to no
* longer invoke |listener| when |messageName| is received.
*
* removeMessageListener does not remove a message listener added via
* addWeakMessageListener; use removeWeakMessageListener for that.
*/
[Throws]
void removeMessageListener(DOMString messageName,
MessageListener listener);
/**
* This is just like addMessageListener, except the message manager holds a
* weak ref to |listener|.
*
* If you have two weak message listeners for the same message, they may be
* called in any order.
*/
[Throws]
void addWeakMessageListener(DOMString messageName,
MessageListener listener);
/**
* This undoes an |addWeakMessageListener| call.
*/
[Throws]
void removeWeakMessageListener(DOMString messageName,
MessageListener listener);
};
[ChromeOnly]
interface MessageSender : MessageListenerManager
{
/**
* Send |messageName| and |obj| to the "other side" of this message
* manager. This invokes listeners who registered for
* |messageName|.
*
* See ReceiveMessageArgument for the format of the data delivered to listeners.
* @throws NS_ERROR_NOT_INITIALIZED if the sender is not initialized. For
* example, we will throw NS_ERROR_NOT_INITIALIZED if we try to send
* a message to a cross-process frame but the other process has not
* yet been set up.
* @throws NS_ERROR_FAILURE when the message receiver cannot be found. For
* example, we will throw NS_ERROR_FAILURE if we try to send a message
* to a cross-process frame whose process has crashed.
*/
[Throws]
void sendAsyncMessage(optional DOMString? messageName = null,
optional any obj,
optional object? objects = null,
optional Principal? principal = null,
optional any transfers);
/**
* For remote browsers there is always a corresponding process message
* manager. The intention of this attribute is to link leaf level frame
* message managers on the parent side with the corresponding process
* message managers (if there is one). For any other cases this property
* is null.
*/
[Throws]
readonly attribute MessageSender? processMessageManager;
/**
* For remote browsers, this contains the remoteType of the content child.
* Otherwise, it is empty.
*/
[Throws]
readonly attribute DOMString remoteType;
};
[ChromeOnly]
interface SyncMessageSender : MessageSender
{
/**
* Like |sendAsyncMessage()|, except blocks the sender until all
* listeners of the message have been invoked. Returns an array
* containing return values from each listener invoked.
*/
[Throws]
sequence<any> sendSyncMessage(optional DOMString? messageName = null,
optional any obj,
optional object? objects = null,
optional Principal? principal = null);
/**
* Like |sendSyncMessage()|, except re-entrant. New RPC messages may be
* issued even if, earlier on the call stack, we are waiting for a reply
* to an earlier sendRpcMessage() call.
*
* Both sendSyncMessage and sendRpcMessage will block until a reply is
* received, but they may be temporarily interrupted to process an urgent
* incoming message (such as a CPOW request).
*/
[Throws]
sequence<any> sendRpcMessage(optional DOMString? messageName = null,
optional any obj,
optional object? objects = null,
optional Principal? principal = null);
};
[ChromeOnly]
interface ChildProcessMessageManager : SyncMessageSender
{
};
[NoInterfaceObject]
interface FrameScriptLoader
{
/**
* Load a script in the (remote) frame. |url| must be the absolute URL.
* data: URLs are also supported. For example data:,dump("foo\n");
* If allowDelayedLoad is true, script will be loaded when the
* remote frame becomes available. Otherwise the script will be loaded
* only if the frame is already available.
*/
[Throws]
void loadFrameScript(DOMString url, boolean allowDelayedLoad,
optional boolean runInGlobalScope = false);
/**
* Removes |url| from the list of scripts which support delayed load.
*/
void removeDelayedFrameScript(DOMString url);
/**
* Returns all delayed scripts that will be loaded once a (remote)
* frame becomes available. The return value is a list of pairs
* [<URL>, <WasLoadedInGlobalScope>].
*/
[Throws]
sequence<sequence<any>> getDelayedFrameScripts();
};
[NoInterfaceObject]
interface ProcessScriptLoader
{
/**
* Load a script in the (possibly remote) process. |url| must be the absolute
* URL. data: URLs are also supported. For example data:,dump("foo\n");
* If allowDelayedLoad is true, script will be loaded when the
* remote frame becomes available. Otherwise the script will be loaded
* only if the frame is already available.
*/
[Throws]
void loadProcessScript(DOMString url, boolean allowDelayedLoad);
/**
* Removes |url| from the list of scripts which support delayed load.
*/
void removeDelayedProcessScript(DOMString url);
/**
* Returns all delayed scripts that will be loaded once a (remote)
* frame becomes available. The return value is a list of pairs
* [<URL>, <WasLoadedInGlobalScope>].
*/
[Throws]
sequence<sequence<any>> getDelayedProcessScripts();
};
[NoInterfaceObject]
interface GlobalProcessScriptLoader : ProcessScriptLoader
{
/**
* Allows the parent process to set the initial process data for
* new, not-yet-created child processes. This attribute should only
* be used by the global parent process message manager. When a new
* process is created, it gets a copy of this data (via structured
* cloning). It can access the data via the initialProcessData
* attribute of its childprocessmessagemanager.
*
* This value will always be a JS object if it's not null or undefined. Different
* users are expected to set properties on this object. The property name should be
* unique enough that other Gecko consumers won't accidentally choose it.
*/
[Throws]
readonly attribute any initialProcessData;
};
[ChromeOnly]
interface ChromeMessageBroadcaster : MessageListenerManager
{
/**
* Like |sendAsyncMessage()|, but also broadcasts this message to
* all "child" message managers of this message manager. See long
* comment above for details.
*
* WARNING: broadcasting messages can be very expensive and leak
* sensitive data. Use with extreme caution.
*/
[Throws]
void broadcastAsyncMessage(optional DOMString? messageName = null,
optional any obj,
optional object? objects = null);
/**
* Number of subordinate message managers.
*/
readonly attribute unsigned long childCount;
/**
* Return a single subordinate message manager.
*/
MessageListenerManager getChildAt(unsigned long aIndex);
/**
* Some processes are kept alive after their last tab/window are closed for testing
* (see dom.ipc.keepProcessesAlive). This function releases those.
*/
void releaseCachedProcesses();
};
ChromeMessageBroadcaster implements GlobalProcessScriptLoader;
ChromeMessageBroadcaster implements FrameScriptLoader;
[ChromeOnly]
interface ChromeMessageSender : MessageSender
{
};
ChromeMessageSender implements ProcessScriptLoader;
ChromeMessageSender implements FrameScriptLoader;

View File

@ -22,7 +22,6 @@
interface ApplicationCache;
interface IID;
interface nsIBrowserDOMWindow;
interface nsIMessageBroadcaster;
interface XULControllers;
// http://www.whatwg.org/specs/web-apps/current-work/
@ -422,14 +421,14 @@ partial interface Window {
void notifyDefaultButtonLoaded(Element defaultButton);
[Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"]
readonly attribute nsIMessageBroadcaster messageManager;
readonly attribute ChromeMessageBroadcaster messageManager;
/**
* Returns the message manager identified by the given group name that
* manages all frame loaders belonging to that group.
*/
[Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"]
nsIMessageBroadcaster getGroupMessageManager(DOMString aGroup);
ChromeMessageBroadcaster getGroupMessageManager(DOMString aGroup);
/**
* On some operating systems, we must allow the window manager to

View File

@ -675,6 +675,7 @@ WEBIDL_FILES = [
'MenuBoxObject.webidl',
'MessageChannel.webidl',
'MessageEvent.webidl',
'MessageManager.webidl',
'MessagePort.webidl',
'MimeType.webidl',
'MimeTypeArray.webidl',

View File

@ -58,6 +58,25 @@ public:
UserDataType Get(KeyType aKey) const;
};
template<typename K, typename T>
inline void
ImplCycleCollectionUnlink(nsClassHashtable<K, T>& aField)
{
aField.Clear();
}
template<typename K, typename T>
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
const nsClassHashtable<K, T>& aField,
const char* aName,
uint32_t aFlags = 0)
{
for (auto iter = aField.ConstIter(); !iter.Done(); iter.Next()) {
ImplCycleCollectionTraverse(aCallback, *iter.UserData(), aName, aFlags);
}
}
//
// nsClassHashtable definitions
//