1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsScriptNameSpaceManager.h"
40 #include "nsIComponentManager.h"
41 #include "nsIComponentRegistrar.h"
42 #include "nsICategoryManager.h"
43 #include "nsIServiceManager.h"
45 #include "nsISupportsPrimitives.h"
46 #include "nsIScriptExternalNameSet.h"
47 #include "nsIScriptNameSpaceManager.h"
48 #include "nsIScriptContext.h"
49 #include "nsIInterfaceInfoManager.h"
50 #include "nsIInterfaceInfo.h"
52 #include "nsXPIDLString.h"
53 #include "nsReadableUtils.h"
54 #include "nsHashKeys.h"
55 #include "nsDOMClassInfo.h"
57 #include "nsIObserverService.h"
59 #define NS_INTERFACE_PREFIX "nsI"
60 #define NS_DOM_INTERFACE_PREFIX "nsIDOM"
62 // Our extended PLDHashEntryHdr
63 class GlobalNameMapEntry
: public PLDHashEntryHdr
66 // Our hash table ops don't care about the order of these members
68 nsGlobalNameStruct mGlobalName
;
73 GlobalNameHashHashKey(PLDHashTable
*table
, const void *key
)
75 const nsAString
*str
= static_cast<const nsAString
*>(key
);
77 return HashString(*str
);
81 GlobalNameHashMatchEntry(PLDHashTable
*table
, const PLDHashEntryHdr
*entry
,
84 const GlobalNameMapEntry
*e
=
85 static_cast<const GlobalNameMapEntry
*>(entry
);
86 const nsAString
*str
= static_cast<const nsAString
*>(key
);
88 return str
->Equals(e
->mKey
);
92 GlobalNameHashClearEntry(PLDHashTable
*table
, PLDHashEntryHdr
*entry
)
94 GlobalNameMapEntry
*e
= static_cast<GlobalNameMapEntry
*>(entry
);
96 // An entry is being cleared, let the key (nsString) do its own
99 if (e
->mGlobalName
.mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
100 nsIClassInfo
* ci
= GET_CLEAN_CI_PTR(e
->mGlobalName
.mData
->mCachedClassInfo
);
102 // If we constructed an internal helper, we'll let the helper delete
103 // the nsDOMClassInfoData structure, if not we do it here.
104 if (!ci
|| e
->mGlobalName
.mData
->u
.mExternalConstructorFptr
) {
105 delete e
->mGlobalName
.mData
;
108 // Release our pointer to the helper.
111 else if (e
->mGlobalName
.mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
112 delete e
->mGlobalName
.mAlias
;
115 // This will set e->mGlobalName.mType to
116 // nsGlobalNameStruct::eTypeNotInitialized
117 memset(&e
->mGlobalName
, 0, sizeof(nsGlobalNameStruct
));
121 GlobalNameHashInitEntry(PLDHashTable
*table
, PLDHashEntryHdr
*entry
,
124 GlobalNameMapEntry
*e
= static_cast<GlobalNameMapEntry
*>(entry
);
125 const nsAString
*keyStr
= static_cast<const nsAString
*>(key
);
127 // Initialize the key in the entry with placement new
128 new (&e
->mKey
) nsString(*keyStr
);
130 // This will set e->mGlobalName.mType to
131 // nsGlobalNameStruct::eTypeNotInitialized
132 memset(&e
->mGlobalName
, 0, sizeof(nsGlobalNameStruct
));
136 NS_IMPL_ISUPPORTS2(nsScriptNameSpaceManager
,
138 nsISupportsWeakReference
)
140 nsScriptNameSpaceManager::nsScriptNameSpaceManager()
141 : mIsInitialized(PR_FALSE
)
143 MOZ_COUNT_CTOR(nsScriptNameSpaceManager
);
146 nsScriptNameSpaceManager::~nsScriptNameSpaceManager()
148 if (mIsInitialized
) {
150 PL_DHashTableFinish(&mGlobalNames
);
152 MOZ_COUNT_DTOR(nsScriptNameSpaceManager
);
156 nsScriptNameSpaceManager::AddToHash(const char *aKey
,
157 const PRUnichar
**aClassName
)
159 NS_ConvertASCIItoUTF16
key(aKey
);
160 GlobalNameMapEntry
*entry
=
161 static_cast<GlobalNameMapEntry
*>
162 (PL_DHashTableOperate(&mGlobalNames
, &key
, PL_DHASH_ADD
));
169 *aClassName
= entry
->mKey
.get();
172 return &entry
->mGlobalName
;
176 nsScriptNameSpaceManager::GetConstructorProto(const nsGlobalNameStruct
* aStruct
)
178 NS_ASSERTION(aStruct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
,
179 "This function only works on constructor aliases!");
180 if (!aStruct
->mAlias
->mProto
) {
181 GlobalNameMapEntry
*proto
=
182 static_cast<GlobalNameMapEntry
*>
183 (PL_DHashTableOperate(&mGlobalNames
,
184 &aStruct
->mAlias
->mProtoName
,
187 if (PL_DHASH_ENTRY_IS_BUSY(proto
)) {
188 aStruct
->mAlias
->mProto
= &proto
->mGlobalName
;
191 return aStruct
->mAlias
->mProto
;
195 nsScriptNameSpaceManager::FillHash(nsICategoryManager
*aCategoryManager
,
196 const char *aCategory
)
198 nsCOMPtr
<nsISimpleEnumerator
> e
;
199 nsresult rv
= aCategoryManager
->EnumerateCategory(aCategory
,
201 NS_ENSURE_SUCCESS(rv
, rv
);
203 nsCOMPtr
<nsISupports
> entry
;
204 while (NS_SUCCEEDED(e
->GetNext(getter_AddRefs(entry
)))) {
205 rv
= AddCategoryEntryToHash(aCategoryManager
, aCategory
, entry
);
215 // This method enumerates over all installed interfaces (in .xpt
216 // files) and finds ones that start with "nsIDOM" and has constants
217 // defined in the interface itself (inherited constants doesn't
218 // count), once such an interface is found the "nsIDOM" prefix is cut
219 // off the name and the rest of the name is added into the hash for
220 // global names. This makes things like 'Node.ELEMENT_NODE' work in
221 // JS. See nsCommonWindowSH::GlobalResolve() for detais on how this is used.
224 nsScriptNameSpaceManager::FillHashWithDOMInterfaces()
226 nsCOMPtr
<nsIInterfaceInfoManager
>
227 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
228 NS_ENSURE_TRUE(iim
, NS_ERROR_UNEXPECTED
);
230 // First look for all interfaces whose name starts with nsIDOM
231 nsCOMPtr
<nsIEnumerator
> domInterfaces
;
233 iim
->EnumerateInterfacesWhoseNamesStartWith(NS_DOM_INTERFACE_PREFIX
,
234 getter_AddRefs(domInterfaces
));
235 NS_ENSURE_SUCCESS(rv
, rv
);
237 nsCOMPtr
<nsISupports
> entry
;
239 rv
= domInterfaces
->First();
242 // Empty interface list?
244 NS_WARNING("What, no nsIDOM interfaces installed?");
250 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
251 const char *if_name
= nsnull
;
254 for ( ; domInterfaces
->IsDone() == NS_ENUMERATOR_FALSE
; domInterfaces
->Next()) {
255 rv
= domInterfaces
->CurrentItem(getter_AddRefs(entry
));
256 NS_ENSURE_SUCCESS(rv
, rv
);
258 nsCOMPtr
<nsIInterfaceInfo
> if_info(do_QueryInterface(entry
));
259 if_info
->GetNameShared(&if_name
);
260 if_info
->GetIIDShared(&iid
);
261 rv
= RegisterInterface(if_name
+ sizeof(NS_DOM_INTERFACE_PREFIX
) - 1,
265 NS_ASSERTION(!found_old
,
266 "Whaaa, interface name already in hash!");
270 // Next, look for externally registered DOM interfaces
271 rv
= RegisterExternalInterfaces(PR_FALSE
);
277 nsScriptNameSpaceManager::RegisterExternalInterfaces(PRBool aAsProto
)
280 nsCOMPtr
<nsICategoryManager
> cm
=
281 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
, &rv
);
282 NS_ENSURE_SUCCESS(rv
, rv
);
284 nsCOMPtr
<nsIInterfaceInfoManager
>
285 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
286 NS_ENSURE_TRUE(iim
, NS_ERROR_NOT_AVAILABLE
);
288 nsCOMPtr
<nsISimpleEnumerator
> enumerator
;
289 rv
= cm
->EnumerateCategory(JAVASCRIPT_DOM_INTERFACE
,
290 getter_AddRefs(enumerator
));
291 NS_ENSURE_SUCCESS(rv
, rv
);
293 nsXPIDLCString IID_string
;
294 nsCAutoString category_entry
;
296 nsCOMPtr
<nsISupports
> entry
;
297 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
298 PRBool found_old
, dom_prefix
;
300 while (NS_SUCCEEDED(enumerator
->GetNext(getter_AddRefs(entry
)))) {
301 nsCOMPtr
<nsISupportsCString
> category(do_QueryInterface(entry
));
304 NS_WARNING("Category entry not an nsISupportsCString!");
309 rv
= category
->GetData(category_entry
);
310 NS_ENSURE_SUCCESS(rv
, rv
);
312 rv
= cm
->GetCategoryEntry(JAVASCRIPT_DOM_INTERFACE
, category_entry
.get(),
313 getter_Copies(IID_string
));
314 NS_ENSURE_SUCCESS(rv
, rv
);
317 if (!primary_IID
.Parse(IID_string
) ||
318 primary_IID
.Equals(NS_GET_IID(nsISupports
))) {
319 NS_ERROR("Invalid IID registered with the script namespace manager!");
323 iim
->GetInfoForIID(&primary_IID
, getter_AddRefs(if_info
));
327 if_info
->GetIIDShared(&iid
);
328 NS_ENSURE_TRUE(iid
, NS_ERROR_UNEXPECTED
);
330 if (iid
->Equals(NS_GET_IID(nsISupports
))) {
334 if_info
->GetNameShared(&if_name
);
335 dom_prefix
= (strncmp(if_name
, NS_DOM_INTERFACE_PREFIX
,
336 sizeof(NS_DOM_INTERFACE_PREFIX
) - 1) == 0);
341 // nsIDOM* interfaces have already been registered.
344 name
= if_name
+ sizeof(NS_DOM_INTERFACE_PREFIX
) - 1;
346 name
= if_name
+ sizeof(NS_INTERFACE_PREFIX
) - 1;
350 RegisterClassProto(name
, iid
, &found_old
);
352 RegisterInterface(name
, iid
, &found_old
);
359 nsCOMPtr
<nsIInterfaceInfo
> tmp(if_info
);
360 tmp
->GetParent(getter_AddRefs(if_info
));
368 nsScriptNameSpaceManager::RegisterInterface(const char* aIfName
,
372 *aFoundOld
= PR_FALSE
;
374 nsGlobalNameStruct
*s
= AddToHash(aIfName
);
375 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
377 if (s
->mType
!= nsGlobalNameStruct::eTypeNotInitialized
) {
378 *aFoundOld
= PR_TRUE
;
383 s
->mType
= nsGlobalNameStruct::eTypeInterface
;
389 #define GLOBALNAME_HASHTABLE_INITIAL_SIZE 1024
392 nsScriptNameSpaceManager::Init()
394 static PLDHashTableOps hash_table_ops
=
398 GlobalNameHashHashKey
,
399 GlobalNameHashMatchEntry
,
400 PL_DHashMoveEntryStub
,
401 GlobalNameHashClearEntry
,
402 PL_DHashFinalizeStub
,
403 GlobalNameHashInitEntry
406 mIsInitialized
= PL_DHashTableInit(&mGlobalNames
, &hash_table_ops
, nsnull
,
407 sizeof(GlobalNameMapEntry
),
408 GLOBALNAME_HASHTABLE_INITIAL_SIZE
);
409 NS_ENSURE_TRUE(mIsInitialized
, NS_ERROR_OUT_OF_MEMORY
);
413 rv
= FillHashWithDOMInterfaces();
414 NS_ENSURE_SUCCESS(rv
, rv
);
416 nsCOMPtr
<nsICategoryManager
> cm
=
417 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
, &rv
);
418 NS_ENSURE_SUCCESS(rv
, rv
);
420 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY
);
421 NS_ENSURE_SUCCESS(rv
, rv
);
423 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY
);
424 NS_ENSURE_SUCCESS(rv
, rv
);
426 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY
);
427 NS_ENSURE_SUCCESS(rv
, rv
);
429 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_STATIC_NAMESET_CATEGORY
);
430 NS_ENSURE_SUCCESS(rv
, rv
);
432 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_DYNAMIC_NAMESET_CATEGORY
);
433 NS_ENSURE_SUCCESS(rv
, rv
);
435 // Initial filling of the has table has been done.
436 // Now, listen for changes.
437 nsCOMPtr
<nsIObserverService
> serv
=
438 do_GetService(NS_OBSERVERSERVICE_CONTRACTID
);
441 serv
->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID
, PR_TRUE
);
447 struct NameSetClosure
{
448 nsIScriptContext
* ctx
;
452 static PLDHashOperator
453 NameSetInitCallback(PLDHashTable
*table
, PLDHashEntryHdr
*hdr
,
454 PRUint32 number
, void *arg
)
456 GlobalNameMapEntry
*entry
= static_cast<GlobalNameMapEntry
*>(hdr
);
458 if (entry
->mGlobalName
.mType
== nsGlobalNameStruct::eTypeStaticNameSet
) {
460 nsCOMPtr
<nsIScriptExternalNameSet
> ns
=
461 do_CreateInstance(entry
->mGlobalName
.mCID
, &rv
);
462 NS_ENSURE_SUCCESS(rv
, PL_DHASH_NEXT
);
464 NameSetClosure
*closure
= static_cast<NameSetClosure
*>(arg
);
465 closure
->rv
= ns
->InitializeNameSet(closure
->ctx
);
466 if (NS_FAILED(closure
->rv
)) {
467 NS_ERROR("Initing external script classes failed!");
468 return PL_DHASH_STOP
;
472 return PL_DHASH_NEXT
;
476 nsScriptNameSpaceManager::InitForContext(nsIScriptContext
*aContext
)
478 NameSetClosure closure
;
479 closure
.ctx
= aContext
;
481 PL_DHashTableEnumerate(&mGlobalNames
, NameSetInitCallback
, &closure
);
487 nsScriptNameSpaceManager::LookupName(const nsAString
& aName
,
488 const nsGlobalNameStruct
**aNameStruct
,
489 const PRUnichar
**aClassName
)
491 GlobalNameMapEntry
*entry
=
492 static_cast<GlobalNameMapEntry
*>
493 (PL_DHashTableOperate(&mGlobalNames
, &aName
,
496 if (PL_DHASH_ENTRY_IS_BUSY(entry
)) {
497 *aNameStruct
= &entry
->mGlobalName
;
499 *aClassName
= entry
->mKey
.get();
502 *aNameStruct
= nsnull
;
504 *aClassName
= nsnull
;
512 nsScriptNameSpaceManager::RegisterClassName(const char *aClassName
,
513 PRInt32 aDOMClassInfoID
,
515 const PRUnichar
**aResult
)
517 if (!nsCRT::IsAscii(aClassName
)) {
518 NS_ERROR("Trying to register a non-ASCII class name");
521 nsGlobalNameStruct
*s
= AddToHash(aClassName
, aResult
);
522 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
524 if (s
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
528 // If a external constructor is already defined with aClassName we
529 // won't overwrite it.
531 if (s
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
) {
535 NS_ASSERTION(s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
536 s
->mType
== nsGlobalNameStruct::eTypeInterface
,
537 "Whaaa, JS environment name clash!");
539 s
->mType
= nsGlobalNameStruct::eTypeClassConstructor
;
540 s
->mDOMClassInfoID
= aDOMClassInfoID
;
541 s
->mChromeOnly
= aPrivileged
;
547 nsScriptNameSpaceManager::RegisterClassProto(const char *aClassName
,
548 const nsIID
*aConstructorProtoIID
,
551 NS_ENSURE_ARG_POINTER(aConstructorProtoIID
);
553 *aFoundOld
= PR_FALSE
;
555 nsGlobalNameStruct
*s
= AddToHash(aClassName
);
556 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
558 if (s
->mType
!= nsGlobalNameStruct::eTypeNotInitialized
&&
559 s
->mType
!= nsGlobalNameStruct::eTypeInterface
) {
560 *aFoundOld
= PR_TRUE
;
565 s
->mType
= nsGlobalNameStruct::eTypeClassProto
;
566 s
->mIID
= *aConstructorProtoIID
;
572 nsScriptNameSpaceManager::RegisterExternalClassName(const char *aClassName
,
575 nsGlobalNameStruct
*s
= AddToHash(aClassName
);
576 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
578 // If an external constructor is already defined with aClassName we
579 // won't overwrite it.
581 if (s
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
) {
585 NS_ASSERTION(s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
586 s
->mType
== nsGlobalNameStruct::eTypeInterface
,
587 "Whaaa, JS environment name clash!");
589 s
->mType
= nsGlobalNameStruct::eTypeExternalClassInfoCreator
;
596 nsScriptNameSpaceManager::RegisterDOMCIData(const char *aName
,
597 nsDOMClassInfoExternalConstructorFnc aConstructorFptr
,
598 const nsIID
*aProtoChainInterface
,
599 const nsIID
**aInterfaces
,
600 PRUint32 aScriptableFlags
,
601 PRBool aHasClassInterface
,
602 const nsCID
*aConstructorCID
)
604 const PRUnichar
* className
;
605 nsGlobalNameStruct
*s
= AddToHash(aName
, &className
);
606 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
608 // If an external constructor is already defined with aClassName we
609 // won't overwrite it.
611 if (s
->mType
== nsGlobalNameStruct::eTypeClassConstructor
||
612 s
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
616 // XXX Should we bail out here?
617 NS_ASSERTION(s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
618 s
->mType
== nsGlobalNameStruct::eTypeExternalClassInfoCreator
,
619 "Someone tries to register classinfo data for a class that isn't new or external!");
621 s
->mData
= new nsExternalDOMClassInfoData
;
622 NS_ENSURE_TRUE(s
->mData
, NS_ERROR_OUT_OF_MEMORY
);
624 s
->mType
= nsGlobalNameStruct::eTypeExternalClassInfo
;
625 s
->mData
->mName
= aName
;
626 s
->mData
->mNameUTF16
= className
;
627 if (aConstructorFptr
)
628 s
->mData
->u
.mExternalConstructorFptr
= aConstructorFptr
;
630 // null constructor will cause us to use nsDOMGenericSH::doCreate
631 s
->mData
->u
.mExternalConstructorFptr
= nsnull
;
632 s
->mData
->mCachedClassInfo
= nsnull
;
633 s
->mData
->mProtoChainInterface
= aProtoChainInterface
;
634 s
->mData
->mInterfaces
= aInterfaces
;
635 s
->mData
->mScriptableFlags
= aScriptableFlags
;
636 s
->mData
->mHasClassInterface
= aHasClassInterface
;
637 s
->mData
->mConstructorCID
= aConstructorCID
;
643 nsScriptNameSpaceManager::AddCategoryEntryToHash(nsICategoryManager
* aCategoryManager
,
644 const char* aCategory
,
647 // Get the type from the category name.
648 // NOTE: we could have passed the type in FillHash() and guessed it in
649 // Observe() but this way, we have only one place to update and this is
650 // not performance sensitive.
651 nsGlobalNameStruct::nametype type
;
652 if (strcmp(aCategory
, JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY
) == 0) {
653 type
= nsGlobalNameStruct::eTypeExternalConstructor
;
654 } else if (strcmp(aCategory
, JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY
) == 0 ||
655 strcmp(aCategory
, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY
) == 0) {
656 type
= nsGlobalNameStruct::eTypeProperty
;
657 } else if (strcmp(aCategory
, JAVASCRIPT_GLOBAL_STATIC_NAMESET_CATEGORY
) == 0) {
658 type
= nsGlobalNameStruct::eTypeStaticNameSet
;
659 } else if (strcmp(aCategory
, JAVASCRIPT_GLOBAL_DYNAMIC_NAMESET_CATEGORY
) == 0) {
660 type
= nsGlobalNameStruct::eTypeDynamicNameSet
;
665 nsCOMPtr
<nsISupportsCString
> strWrapper
= do_QueryInterface(aEntry
);
668 NS_WARNING("Category entry not an nsISupportsCString!");
672 nsCAutoString categoryEntry
;
673 nsresult rv
= strWrapper
->GetData(categoryEntry
);
674 NS_ENSURE_SUCCESS(rv
, rv
);
676 nsXPIDLCString contractId
;
677 rv
= aCategoryManager
->GetCategoryEntry(aCategory
, categoryEntry
.get(),
678 getter_Copies(contractId
));
679 NS_ENSURE_SUCCESS(rv
, rv
);
681 nsCOMPtr
<nsIComponentRegistrar
> registrar
;
682 rv
= NS_GetComponentRegistrar(getter_AddRefs(registrar
));
683 NS_ENSURE_SUCCESS(rv
, rv
);
686 rv
= registrar
->ContractIDToCID(contractId
, &cidPtr
);
689 NS_WARNING("Bad contract id registed with the script namespace manager");
693 // Copy CID onto the stack, so we can free it right away and avoid having
694 // to add cleanup code at every exit point from this function.
696 nsMemory::Free(cidPtr
);
698 if (type
== nsGlobalNameStruct::eTypeExternalConstructor
) {
699 nsXPIDLCString constructorProto
;
700 rv
= aCategoryManager
->GetCategoryEntry(JAVASCRIPT_GLOBAL_CONSTRUCTOR_PROTO_ALIAS_CATEGORY
,
702 getter_Copies(constructorProto
));
703 if (NS_SUCCEEDED(rv
)) {
704 nsGlobalNameStruct
*s
= AddToHash(categoryEntry
.get());
705 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
707 if (s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
) {
708 s
->mAlias
= new nsGlobalNameStruct::ConstructorAlias
;
709 s
->mType
= nsGlobalNameStruct::eTypeExternalConstructorAlias
;
710 s
->mChromeOnly
= PR_FALSE
;
711 s
->mAlias
->mCID
= cid
;
712 AppendASCIItoUTF16(constructorProto
, s
->mAlias
->mProtoName
);
713 s
->mAlias
->mProto
= nsnull
;
715 NS_WARNING("Global script name not overwritten!");
722 nsGlobalNameStruct
*s
= AddToHash(categoryEntry
.get());
723 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
725 if (s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
) {
729 strcmp(aCategory
, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY
) == 0;
731 NS_WARNING("Global script name not overwritten!");
738 nsScriptNameSpaceManager::Observe(nsISupports
* aSubject
, const char* aTopic
,
739 const PRUnichar
* aData
)
745 if (strcmp(aTopic
, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID
) == 0) {
746 nsCOMPtr
<nsICategoryManager
> cm
=
747 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
);
752 return AddCategoryEntryToHash(cm
, NS_ConvertUTF16toUTF8(aData
).get(),
756 // TODO: we could observe NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID
757 // and NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID but we are safe without it.