Fix for bug 764277 (New DOM bindings codegen doesn't register classes with constructors). r=jst.

This commit is contained in:
Peter Van der Beken 2012-06-14 16:56:38 +02:00
Родитель 79a7876dd9
Коммит a69b9ca912
3 изменённых файлов: 74 добавлений и 56 удалений

Просмотреть файл

@ -6751,6 +6751,34 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
return NS_OK;
}
static bool
ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin)
{
MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor ||
aStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo);
// Don't expose chrome only constructors to content windows.
if (aStruct->mChromeOnly &&
!nsContentUtils::IsSystemPrincipal(aWin->GetPrincipal())) {
return false;
}
// For now don't expose web sockets unless user has explicitly enabled them
if (aStruct->mDOMClassInfoID == eDOMClassInfo_WebSocket_id) {
if (!nsWebSocket::PrefEnabled()) {
return false;
}
}
// For now don't expose server events unless user has explicitly enabled them
if (aStruct->mDOMClassInfoID == eDOMClassInfo_EventSource_id) {
if (!nsEventSource::PrefEnabled()) {
return false;
}
}
return true;
}
// static
nsresult
@ -6785,19 +6813,30 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
}
}
if (name_struct->mType == nsGlobalNameStruct::eTypeInterface) {
// We're resolving a name of a DOM interface for which there is no
// direct DOM class, create a constructor object...
if (name_struct->mType == nsGlobalNameStruct::eTypeNewDOMBinding ||
name_struct->mType == nsGlobalNameStruct::eTypeInterface ||
name_struct->mType == nsGlobalNameStruct::eTypeClassProto ||
name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
// Lookup new DOM bindings.
mozilla::dom::binding::DefineInterface define =
name_struct->mDefineDOMInterface;
if (define && mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
if (define) {
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
!ConstructorEnabled(name_struct, aWin)) {
return NS_OK;
}
return rv;
if (mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return rv;
}
}
}
if (name_struct->mType == nsGlobalNameStruct::eTypeInterface) {
// We're resolving a name of a DOM interface for which there is no
// direct DOM class, create a constructor object...
nsRefPtr<nsDOMConstructor> constructor;
rv = nsDOMConstructor::Create(class_name,
nsnull,
@ -6832,37 +6871,10 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor ||
name_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
// Don't expose chrome only constructors to content windows.
if (name_struct->mChromeOnly &&
!nsContentUtils::IsSystemPrincipal(aWin->GetPrincipal())) {
if (!ConstructorEnabled(name_struct, aWin)) {
return NS_OK;
}
// For now don't expose web sockets unless user has explicitly enabled them
if (name_struct->mDOMClassInfoID == eDOMClassInfo_WebSocket_id) {
if (!nsWebSocket::PrefEnabled()) {
return NS_OK;
}
}
// For now don't expose server events unless user has explicitly enabled them
if (name_struct->mDOMClassInfoID == eDOMClassInfo_EventSource_id) {
if (!nsEventSource::PrefEnabled()) {
return NS_OK;
}
}
// Lookup new DOM bindings.
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
mozilla::dom::binding::DefineInterface define =
name_struct->mDefineDOMInterface;
if (define && mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return rv;
}
}
// Create the XPConnect prototype for our classinfo, PostCreateProto will
// set up the prototype chain.
nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
@ -6894,16 +6906,6 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
// We don't have a XPConnect prototype object, let ResolvePrototype create
// one.
// Lookup new DOM bindings.
mozilla::dom::binding::DefineInterface define =
name_struct->mDefineDOMInterface;
if (define && mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return rv;
}
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, nsnull,
name_struct, nameSpaceManager, nsnull, true,
did_resolve);

Просмотреть файл

@ -124,13 +124,12 @@ nsScriptNameSpaceManager::~nsScriptNameSpaceManager()
}
nsGlobalNameStruct *
nsScriptNameSpaceManager::AddToHash(PLDHashTable *aTable, const char *aKey,
nsScriptNameSpaceManager::AddToHash(PLDHashTable *aTable, const nsAString *aKey,
const PRUnichar **aClassName)
{
NS_ConvertASCIItoUTF16 key(aKey);
GlobalNameMapEntry *entry =
static_cast<GlobalNameMapEntry *>
(PL_DHashTableOperate(aTable, &key, PL_DHASH_ADD));
(PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD));
if (!entry) {
return nsnull;
@ -345,7 +344,8 @@ nsScriptNameSpaceManager::RegisterInterface(const char* aIfName,
nsGlobalNameStruct *s = AddToHash(&mGlobalNames, aIfName);
NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
if (s->mType != nsGlobalNameStruct::eTypeNotInitialized) {
if (s->mType != nsGlobalNameStruct::eTypeNotInitialized &&
s->mType != nsGlobalNameStruct::eTypeNewDOMBinding) {
*aFoundOld = true;
return NS_OK;
@ -534,6 +534,7 @@ nsScriptNameSpaceManager::RegisterClassName(const char *aClassName,
}
NS_ASSERTION(s->mType == nsGlobalNameStruct::eTypeNotInitialized ||
s->mType == nsGlobalNameStruct::eTypeNewDOMBinding ||
s->mType == nsGlobalNameStruct::eTypeInterface,
"Whaaa, JS environment name clash!");
@ -558,6 +559,7 @@ nsScriptNameSpaceManager::RegisterClassProto(const char *aClassName,
NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
if (s->mType != nsGlobalNameStruct::eTypeNotInitialized &&
s->mType != nsGlobalNameStruct::eTypeNewDOMBinding &&
s->mType != nsGlobalNameStruct::eTypeInterface) {
*aFoundOld = true;
@ -585,6 +587,7 @@ nsScriptNameSpaceManager::RegisterExternalClassName(const char *aClassName,
}
NS_ASSERTION(s->mType == nsGlobalNameStruct::eTypeNotInitialized ||
s->mType == nsGlobalNameStruct::eTypeNewDOMBinding ||
s->mType == nsGlobalNameStruct::eTypeInterface,
"Whaaa, JS environment name clash!");
@ -617,6 +620,7 @@ nsScriptNameSpaceManager::RegisterDOMCIData(const char *aName,
// XXX Should we bail out here?
NS_ASSERTION(s->mType == nsGlobalNameStruct::eTypeNotInitialized ||
s->mType == nsGlobalNameStruct::eTypeNewDOMBinding ||
s->mType == nsGlobalNameStruct::eTypeExternalClassInfoCreator,
"Someone tries to register classinfo data for a class that isn't new or external!");
@ -708,7 +712,8 @@ nsScriptNameSpaceManager::AddCategoryEntryToHash(nsICategoryManager* aCategoryMa
nsGlobalNameStruct *s = AddToHash(&mGlobalNames, categoryEntry.get());
NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
if (s->mType == nsGlobalNameStruct::eTypeNotInitialized) {
if (s->mType == nsGlobalNameStruct::eTypeNotInitialized ||
s->mType == nsGlobalNameStruct::eTypeNewDOMBinding) {
s->mAlias = new nsGlobalNameStruct::ConstructorAlias;
s->mType = nsGlobalNameStruct::eTypeExternalConstructorAlias;
s->mChromeOnly = false;
@ -733,7 +738,8 @@ nsScriptNameSpaceManager::AddCategoryEntryToHash(nsICategoryManager* aCategoryMa
nsGlobalNameStruct *s = AddToHash(table, categoryEntry.get());
NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
if (s->mType == nsGlobalNameStruct::eTypeNotInitialized) {
if (s->mType == nsGlobalNameStruct::eTypeNotInitialized ||
s->mType == nsGlobalNameStruct::eTypeNewDOMBinding) {
s->mType = type;
s->mCID = cid;
s->mChromeOnly =
@ -772,11 +778,14 @@ nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic,
}
void
nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAString& aName,
nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName,
mozilla::dom::binding::DefineInterface aDefineDOMInterface)
{
nsGlobalNameStruct* s = LookupNameInternal(aName);
nsGlobalNameStruct *s = AddToHash(&mGlobalNames, &aName);
if (s) {
if (s->mType == nsGlobalNameStruct::eTypeNotInitialized) {
s->mType = nsGlobalNameStruct::eTypeNewDOMBinding;
}
s->mDefineDOMInterface = aDefineDOMInterface;
}
}

Просмотреть файл

@ -41,6 +41,7 @@ struct nsGlobalNameStruct
enum nametype {
eTypeNotInitialized,
eTypeNewDOMBinding,
eTypeInterface,
eTypeProperty,
eTypeNavigatorProperty,
@ -62,7 +63,7 @@ struct nsGlobalNameStruct
nsIID mIID; // eTypeInterface, eTypeClassProto
nsExternalDOMClassInfoData* mData; // eTypeExternalClassInfo
ConstructorAlias* mAlias; // eTypeExternalConstructorAlias
nsCID mCID; // All other types...
nsCID mCID; // All other types except eTypeNewDOMBinding
};
// For new style DOM bindings.
@ -137,7 +138,7 @@ public:
nsGlobalNameStruct* GetConstructorProto(const nsGlobalNameStruct* aStruct);
void RegisterDefineDOMInterface(const nsAString& aName,
void RegisterDefineDOMInterface(const nsAFlatString& aName,
mozilla::dom::binding::DefineInterface aDefineDOMInterface);
private:
@ -145,8 +146,14 @@ private:
// that aKey will be mapped to. If mType in the returned
// nsGlobalNameStruct is != eTypeNotInitialized, an entry for aKey
// already existed.
nsGlobalNameStruct *AddToHash(PLDHashTable *aTable, const char *aKey,
nsGlobalNameStruct *AddToHash(PLDHashTable *aTable, const nsAString *aKey,
const PRUnichar **aClassName = nsnull);
nsGlobalNameStruct *AddToHash(PLDHashTable *aTable, const char *aKey,
const PRUnichar **aClassName = nsnull)
{
NS_ConvertASCIItoUTF16 key(aKey);
return AddToHash(aTable, &key, aClassName);
}
nsresult FillHash(nsICategoryManager *aCategoryManager,
const char *aCategory);