Bug 319968 - "Some DOM functions don't work in XPCShell (classinfo broken)" [p=Mossop r+sr=jst a1.9=schrep]

This commit is contained in:
reed@reedloden.com 2007-11-13 02:35:49 -08:00
parent 6d55f2669a
commit adc94d0618
6 changed files with 124 additions and 56 deletions

View File

@ -93,6 +93,7 @@
#include "nsScriptNameSpaceManager.h"
#include "nsIScriptObjectOwner.h"
#include "nsIJSNativeInitializer.h"
#include "nsJSEnvironment.h"
// DOM base includes
#include "nsIDOMPluginArray.h"
@ -1665,11 +1666,11 @@ CutPrefix(const char *aName) {
nsresult
nsDOMClassInfo::RegisterClassName(PRInt32 aClassInfoID)
{
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
gNameSpaceManager->RegisterClassName(sClassInfoData[aClassInfoID].mName,
aClassInfoID);
nameSpaceManager->RegisterClassName(sClassInfoData[aClassInfoID].mName,
aClassInfoID);
return NS_OK;
}
@ -1678,8 +1679,8 @@ nsDOMClassInfo::RegisterClassName(PRInt32 aClassInfoID)
nsresult
nsDOMClassInfo::RegisterClassProtos(PRInt32 aClassInfoID)
{
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
PRBool found_old;
const nsIID *primary_iid = sClassInfoData[aClassInfoID].mProtoChainInterface;
@ -1712,7 +1713,7 @@ nsDOMClassInfo::RegisterClassProtos(PRInt32 aClassInfoID)
nsXPIDLCString name;
if_info->GetName(getter_Copies(name));
gNameSpaceManager->RegisterClassProto(CutPrefix(name), iid, &found_old);
nameSpaceManager->RegisterClassProto(CutPrefix(name), iid, &found_old);
nsMemory::Free(iid);
@ -1733,12 +1734,11 @@ nsDOMClassInfo::RegisterClassProtos(PRInt32 aClassInfoID)
nsresult
nsDOMClassInfo::RegisterExternalClasses()
{
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsresult rv;
nsCOMPtr<nsIComponentRegistrar> registrar;
rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICategoryManager> cm =
@ -1774,12 +1774,12 @@ nsDOMClassInfo::RegisterExternalClasses()
continue;
}
rv = gNameSpaceManager->RegisterExternalClassName(categoryEntry.get(), *cid);
rv = nameSpaceManager->RegisterExternalClassName(categoryEntry.get(), *cid);
nsMemory::Free(cid);
NS_ENSURE_SUCCESS(rv, rv);
}
return gNameSpaceManager->RegisterExternalInterfaces(PR_TRUE);
return nameSpaceManager->RegisterExternalInterfaces(PR_TRUE);
}
#define _DOM_CLASSINFO_MAP_BEGIN(_class, _ifptr, _has_class_if) \
@ -1846,8 +1846,8 @@ nsDOMClassInfo::Init()
NS_ENSURE_TRUE(!sIsInitialized, NS_ERROR_ALREADY_INITIALIZED);
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsresult rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect);
NS_ENSURE_SUCCESS(rv, rv);
@ -4902,13 +4902,13 @@ private:
{
*aNameStruct = nsnull;
extern nsScriptNameSpaceManager *gNameSpaceManager;
if (!gNameSpaceManager) {
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
if (!nameSpaceManager) {
NS_ERROR("Can't get namespace manager.");
return NS_ERROR_UNEXPECTED;
}
gNameSpaceManager->LookupName(aName, aNameStruct);
nameSpaceManager->LookupName(aName, aNameStruct);
// Return NS_OK here, aName just isn't a DOM class but nothing failed.
return NS_OK;
@ -5029,8 +5029,8 @@ nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
return NS_OK;
}
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ASSERTION(gNameSpaceManager, "Can't get namespace manager?");
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ASSERTION(nameSpaceManager, "Can't get namespace manager?");
const nsIID *class_iid;
if (class_name_struct->mType == nsGlobalNameStruct::eTypeInterface ||
@ -5043,7 +5043,7 @@ nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
class_iid = class_name_struct->mData->mProtoChainInterface;
} else if (class_name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructorAlias) {
const nsGlobalNameStruct* alias_struct =
gNameSpaceManager->GetConstructorProto(class_name_struct);
nameSpaceManager->GetConstructorProto(class_name_struct);
if (!alias_struct) {
NS_ERROR("Couldn't get constructor prototype.");
return NS_ERROR_UNEXPECTED;
@ -5065,7 +5065,7 @@ nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
}
if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructorAlias) {
name_struct = gNameSpaceManager->GetConstructorProto(name_struct);
name_struct = nameSpaceManager->GetConstructorProto(name_struct);
if (!name_struct) {
NS_ERROR("Couldn't get constructor prototype.");
return NS_ERROR_UNEXPECTED;
@ -5135,16 +5135,15 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
{
*did_resolve = PR_FALSE;
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsDependentJSString name(str);
const nsGlobalNameStruct *name_struct = nsnull;
const PRUnichar *class_name = nsnull;
gNameSpaceManager->LookupName(name, &name_struct, &class_name);
nameSpaceManager->LookupName(name, &name_struct, &class_name);
if (!name_struct) {
return NS_OK;
@ -5164,7 +5163,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
rv = creator->RegisterDOMCI(NS_ConvertUTF16toUTF8(name).get(), sof);
NS_ENSURE_SUCCESS(rv, rv);
rv = gNameSpaceManager->LookupName(name, &name_struct);
rv = nameSpaceManager->LookupName(name, &name_struct);
if (NS_FAILED(rv) || !name_struct ||
name_struct->mType != nsGlobalNameStruct::eTypeExternalClassInfo) {
NS_ERROR("Couldn't get the DOM ClassInfo data.");
@ -5229,7 +5228,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
} else if (name_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
ci_data = name_struct->mData;
} else if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructorAlias) {
alias_struct = gNameSpaceManager->GetConstructorProto(name_struct);
alias_struct = nameSpaceManager->GetConstructorProto(name_struct);
NS_ENSURE_TRUE(alias_struct, NS_ERROR_UNEXPECTED);
if (alias_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {

View File

@ -227,12 +227,11 @@ nsDOMScriptObjectFactory::GetClassInfoInstance(nsDOMClassInfoID aID)
NS_IMETHODIMP_(nsISupports *)
nsDOMScriptObjectFactory::GetExternalClassInfoInstance(const nsAString& aName)
{
extern nsScriptNameSpaceManager *gNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, nsnull);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, nsnull);
const nsGlobalNameStruct *globalStruct;
gNameSpaceManager->LookupName(aName, &globalStruct);
nameSpaceManager->LookupName(aName, &globalStruct);
if (globalStruct) {
if (globalStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfoCreator) {
nsresult rv;
@ -242,7 +241,7 @@ nsDOMScriptObjectFactory::GetExternalClassInfoInstance(const nsAString& aName)
rv = creator->RegisterDOMCI(NS_ConvertUTF16toUTF8(aName).get(), this);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = gNameSpaceManager->LookupName(aName, &globalStruct);
rv = nameSpaceManager->LookupName(aName, &globalStruct);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && globalStruct, nsnull);
NS_ASSERTION(globalStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo,
@ -367,17 +366,16 @@ nsDOMScriptObjectFactory::RegisterDOMClassInfo(const char *aName,
PRBool aHasClassInterface,
const nsCID *aConstructorCID)
{
extern nsScriptNameSpaceManager *gNameSpaceManager;
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
return gNameSpaceManager->RegisterDOMCIData(aName,
aConstructorFptr,
aProtoChainInterface,
aInterfaces,
aScriptableFlags,
aHasClassInterface,
aConstructorCID);
return nameSpaceManager->RegisterDOMCIData(aName,
aConstructorFptr,
aProtoChainInterface,
aInterfaces,
aScriptableFlags,
aHasClassInterface,
aConstructorCID);
}
/* static */ nsresult

View File

@ -72,7 +72,6 @@
#include "nsIPrompt.h"
#include "nsIObserverService.h"
#include "nsGUIEvent.h"
#include "nsScriptNameSpaceManager.h"
#include "nsThreadUtils.h"
#include "nsITimer.h"
#include "nsIAtom.h"
@ -2315,16 +2314,6 @@ nsJSContext::InitContext(nsIScriptGlobalObject *aGlobalObject)
if (!mContext)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
if (!gNameSpaceManager) {
gNameSpaceManager = new nsScriptNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_OUT_OF_MEMORY);
rv = gNameSpaceManager->Init();
NS_ENSURE_SUCCESS(rv, rv);
}
::JS_SetErrorReporter(mContext, NS_ScriptErrorReporter);
if (!aGlobalObject) {
@ -2342,6 +2331,8 @@ nsJSContext::InitContext(nsIScriptGlobalObject *aGlobalObject)
// If there's already a global object in mContext we won't tell
// XPConnect to wrap aGlobalObject since it's already wrapped.
nsresult rv;
if (!global) {
nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(aGlobalObject));
PRUint32 flags = 0;
@ -2413,9 +2404,10 @@ nsJSContext::InitContext(nsIScriptGlobalObject *aGlobalObject)
nsresult
nsJSContext::InitializeExternalClasses()
{
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
return gNameSpaceManager->InitForContext(this);
return nameSpaceManager->InitForContext(this);
}
nsresult
@ -3662,6 +3654,24 @@ nsJSRuntime::Init()
return rv;
}
//static
nsScriptNameSpaceManager*
nsJSRuntime::GetNameSpaceManager()
{
if (sDidShutdown)
return nsnull;
if (!gNameSpaceManager) {
gNameSpaceManager = new nsScriptNameSpaceManager;
NS_ENSURE_TRUE(gNameSpaceManager, nsnull);
nsresult rv = gNameSpaceManager->Init();
NS_ENSURE_SUCCESS(rv, nsnull);
}
return gNameSpaceManager;
}
void nsJSRuntime::ShutDown()
{
if (sGCTimer) {

View File

@ -46,6 +46,7 @@
#include "nsITimer.h"
#include "prtime.h"
#include "nsCycleCollectionParticipant.h"
#include "nsScriptNameSpaceManager.h"
class nsIXPConnectJSObjectHolder;
@ -326,6 +327,8 @@ public:
static void Startup();
// Setup all the statics etc - safe to call multiple times after Startup()
static nsresult Init();
// Get the NameSpaceManager, creating if necessary
static nsScriptNameSpaceManager* GetNameSpaceManager();
};
// An interface for fast and native conversion to/from nsIArray. If an object

View File

@ -42,9 +42,15 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = test_dom
ifdef MOZ_MOCHITEST
DIRS += mochitest
endif
ifdef ENABLE_TESTS
XPCSHELL_TESTS = unit
endif
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,52 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Dave Townsend <dtownsend@oxymoronical.com>.
*
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK *****
*/
function run_test()
{
var domParser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser);
var aDom = domParser.parseFromString("<root><feed><entry/><entry/></feed></root>",
"application/xml");
var feedList = aDom.getElementsByTagName("feed");
do_check_neq(feedList, null);
do_check_eq(feedList.length, 1);
do_check_neq(feedList[0], null);
do_check_eq(feedList[0].tagName, "feed");
var entry = feedList[0].getElementsByTagName("entry");
do_check_neq(entry, null);
}