1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsScriptNameSpaceManager.h"
9 #include "nsIComponentManager.h"
10 #include "nsIComponentRegistrar.h"
11 #include "nsICategoryManager.h"
12 #include "nsIServiceManager.h"
14 #include "nsISupportsPrimitives.h"
15 #include "nsIScriptNameSpaceManager.h"
16 #include "nsIScriptContext.h"
17 #include "nsIInterfaceInfoManager.h"
18 #include "nsIInterfaceInfo.h"
20 #include "nsXPIDLString.h"
21 #include "nsPrintfCString.h"
22 #include "nsReadableUtils.h"
23 #include "nsHashKeys.h"
24 #include "nsDOMClassInfo.h"
26 #include "nsIObserverService.h"
27 #include "nsISimpleEnumerator.h"
29 #include "mozilla/MemoryReporting.h"
30 #include "mozilla/Preferences.h"
31 #include "mozilla/Services.h"
33 #define NS_INTERFACE_PREFIX "nsI"
34 #define NS_DOM_INTERFACE_PREFIX "nsIDOM"
36 using namespace mozilla
;
38 // Our extended PLDHashEntryHdr
39 class GlobalNameMapEntry
: public PLDHashEntryHdr
42 // Our hash table ops don't care about the order of these members
44 nsGlobalNameStruct mGlobalName
;
46 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) {
47 // Measurement of the following members may be added later if DMD finds it
50 return mKey
.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf
);
56 GlobalNameHashHashKey(PLDHashTable
*table
, const void *key
)
58 const nsAString
*str
= static_cast<const nsAString
*>(key
);
59 return HashString(*str
);
63 GlobalNameHashMatchEntry(PLDHashTable
*table
, const PLDHashEntryHdr
*entry
,
66 const GlobalNameMapEntry
*e
=
67 static_cast<const GlobalNameMapEntry
*>(entry
);
68 const nsAString
*str
= static_cast<const nsAString
*>(key
);
70 return str
->Equals(e
->mKey
);
74 GlobalNameHashClearEntry(PLDHashTable
*table
, PLDHashEntryHdr
*entry
)
76 GlobalNameMapEntry
*e
= static_cast<GlobalNameMapEntry
*>(entry
);
78 // An entry is being cleared, let the key (nsString) do its own
81 if (e
->mGlobalName
.mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
82 nsIClassInfo
* ci
= GET_CLEAN_CI_PTR(e
->mGlobalName
.mData
->mCachedClassInfo
);
84 // If we constructed an internal helper, we'll let the helper delete
85 // the nsDOMClassInfoData structure, if not we do it here.
86 if (!ci
|| e
->mGlobalName
.mData
->u
.mExternalConstructorFptr
) {
87 delete e
->mGlobalName
.mData
;
90 // Release our pointer to the helper.
93 else if (e
->mGlobalName
.mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
94 delete e
->mGlobalName
.mAlias
;
97 // This will set e->mGlobalName.mType to
98 // nsGlobalNameStruct::eTypeNotInitialized
99 memset(&e
->mGlobalName
, 0, sizeof(nsGlobalNameStruct
));
103 GlobalNameHashInitEntry(PLDHashTable
*table
, PLDHashEntryHdr
*entry
,
106 GlobalNameMapEntry
*e
= static_cast<GlobalNameMapEntry
*>(entry
);
107 const nsAString
*keyStr
= static_cast<const nsAString
*>(key
);
109 // Initialize the key in the entry with placement new
110 new (&e
->mKey
) nsString(*keyStr
);
112 // This will set e->mGlobalName.mType to
113 // nsGlobalNameStruct::eTypeNotInitialized
114 memset(&e
->mGlobalName
, 0, sizeof(nsGlobalNameStruct
));
119 nsScriptNameSpaceManager
,
121 nsISupportsWeakReference
,
124 nsScriptNameSpaceManager::nsScriptNameSpaceManager()
125 : mIsInitialized(false)
127 MOZ_COUNT_CTOR(nsScriptNameSpaceManager
);
130 nsScriptNameSpaceManager::~nsScriptNameSpaceManager()
132 if (mIsInitialized
) {
133 UnregisterWeakMemoryReporter(this);
135 PL_DHashTableFinish(&mGlobalNames
);
136 PL_DHashTableFinish(&mNavigatorNames
);
138 MOZ_COUNT_DTOR(nsScriptNameSpaceManager
);
142 nsScriptNameSpaceManager::AddToHash(PLDHashTable
*aTable
, const nsAString
*aKey
,
143 const char16_t
**aClassName
)
145 GlobalNameMapEntry
*entry
=
146 static_cast<GlobalNameMapEntry
*>
147 (PL_DHashTableOperate(aTable
, aKey
, PL_DHASH_ADD
));
154 *aClassName
= entry
->mKey
.get();
157 return &entry
->mGlobalName
;
161 nsScriptNameSpaceManager::RemoveFromHash(PLDHashTable
*aTable
,
162 const nsAString
*aKey
)
164 PL_DHashTableOperate(aTable
, aKey
, PL_DHASH_REMOVE
);
168 nsScriptNameSpaceManager::GetConstructorProto(const nsGlobalNameStruct
* aStruct
)
170 NS_ASSERTION(aStruct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
,
171 "This function only works on constructor aliases!");
172 if (!aStruct
->mAlias
->mProto
) {
173 GlobalNameMapEntry
*proto
=
174 static_cast<GlobalNameMapEntry
*>
175 (PL_DHashTableOperate(&mGlobalNames
,
176 &aStruct
->mAlias
->mProtoName
,
179 if (PL_DHASH_ENTRY_IS_BUSY(proto
)) {
180 aStruct
->mAlias
->mProto
= &proto
->mGlobalName
;
183 return aStruct
->mAlias
->mProto
;
187 nsScriptNameSpaceManager::FillHash(nsICategoryManager
*aCategoryManager
,
188 const char *aCategory
)
190 nsCOMPtr
<nsISimpleEnumerator
> e
;
191 nsresult rv
= aCategoryManager
->EnumerateCategory(aCategory
,
193 NS_ENSURE_SUCCESS(rv
, rv
);
195 nsCOMPtr
<nsISupports
> entry
;
196 while (NS_SUCCEEDED(e
->GetNext(getter_AddRefs(entry
)))) {
197 rv
= AddCategoryEntryToHash(aCategoryManager
, aCategory
, entry
);
208 nsScriptNameSpaceManager::RegisterExternalInterfaces(bool aAsProto
)
211 nsCOMPtr
<nsICategoryManager
> cm
=
212 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
, &rv
);
213 NS_ENSURE_SUCCESS(rv
, rv
);
215 nsCOMPtr
<nsIInterfaceInfoManager
>
216 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
217 NS_ENSURE_TRUE(iim
, NS_ERROR_NOT_AVAILABLE
);
219 nsCOMPtr
<nsISimpleEnumerator
> enumerator
;
220 rv
= cm
->EnumerateCategory(JAVASCRIPT_DOM_INTERFACE
,
221 getter_AddRefs(enumerator
));
222 NS_ENSURE_SUCCESS(rv
, rv
);
224 nsXPIDLCString IID_string
;
225 nsAutoCString category_entry
;
227 nsCOMPtr
<nsISupports
> entry
;
228 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
229 bool found_old
, dom_prefix
;
231 while (NS_SUCCEEDED(enumerator
->GetNext(getter_AddRefs(entry
)))) {
232 nsCOMPtr
<nsISupportsCString
> category(do_QueryInterface(entry
));
235 NS_WARNING("Category entry not an nsISupportsCString!");
240 rv
= category
->GetData(category_entry
);
241 NS_ENSURE_SUCCESS(rv
, rv
);
243 rv
= cm
->GetCategoryEntry(JAVASCRIPT_DOM_INTERFACE
, category_entry
.get(),
244 getter_Copies(IID_string
));
245 NS_ENSURE_SUCCESS(rv
, rv
);
248 if (!primary_IID
.Parse(IID_string
) ||
249 primary_IID
.Equals(NS_GET_IID(nsISupports
))) {
250 NS_ERROR("Invalid IID registered with the script namespace manager!");
254 iim
->GetInfoForIID(&primary_IID
, getter_AddRefs(if_info
));
258 if_info
->GetIIDShared(&iid
);
259 NS_ENSURE_TRUE(iid
, NS_ERROR_UNEXPECTED
);
261 if (iid
->Equals(NS_GET_IID(nsISupports
))) {
265 if_info
->GetNameShared(&if_name
);
266 dom_prefix
= (strncmp(if_name
, NS_DOM_INTERFACE_PREFIX
,
267 sizeof(NS_DOM_INTERFACE_PREFIX
) - 1) == 0);
271 name
= if_name
+ sizeof(NS_DOM_INTERFACE_PREFIX
) - 1;
273 name
= if_name
+ sizeof(NS_INTERFACE_PREFIX
) - 1;
277 RegisterClassProto(name
, iid
, &found_old
);
279 RegisterInterface(name
, iid
, &found_old
);
286 nsCOMPtr
<nsIInterfaceInfo
> tmp(if_info
);
287 tmp
->GetParent(getter_AddRefs(if_info
));
295 nsScriptNameSpaceManager::RegisterInterface(const char* aIfName
,
301 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, aIfName
);
302 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
304 if (s
->mType
!= nsGlobalNameStruct::eTypeNotInitialized
&&
305 s
->mType
!= nsGlobalNameStruct::eTypeNewDOMBinding
) {
311 s
->mType
= nsGlobalNameStruct::eTypeInterface
;
317 #define GLOBALNAME_HASHTABLE_INITIAL_LENGTH 512
320 nsScriptNameSpaceManager::Init()
322 static const PLDHashTableOps hash_table_ops
=
326 GlobalNameHashHashKey
,
327 GlobalNameHashMatchEntry
,
328 PL_DHashMoveEntryStub
,
329 GlobalNameHashClearEntry
,
330 PL_DHashFinalizeStub
,
331 GlobalNameHashInitEntry
334 mIsInitialized
= PL_DHashTableInit(&mGlobalNames
, &hash_table_ops
,
335 nullptr, sizeof(GlobalNameMapEntry
),
337 GLOBALNAME_HASHTABLE_INITIAL_LENGTH
);
338 NS_ENSURE_TRUE(mIsInitialized
, NS_ERROR_OUT_OF_MEMORY
);
340 mIsInitialized
= PL_DHashTableInit(&mNavigatorNames
, &hash_table_ops
,
341 nullptr, sizeof(GlobalNameMapEntry
),
343 GLOBALNAME_HASHTABLE_INITIAL_LENGTH
);
344 if (!mIsInitialized
) {
345 PL_DHashTableFinish(&mGlobalNames
);
347 return NS_ERROR_OUT_OF_MEMORY
;
350 RegisterWeakMemoryReporter(this);
354 rv
= RegisterExternalInterfaces(false);
355 NS_ENSURE_SUCCESS(rv
, rv
);
357 nsCOMPtr
<nsICategoryManager
> cm
=
358 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
, &rv
);
359 NS_ENSURE_SUCCESS(rv
, rv
);
361 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY
);
362 NS_ENSURE_SUCCESS(rv
, rv
);
364 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY
);
365 NS_ENSURE_SUCCESS(rv
, rv
);
367 rv
= FillHash(cm
, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY
);
368 NS_ENSURE_SUCCESS(rv
, rv
);
370 rv
= FillHash(cm
, JAVASCRIPT_NAVIGATOR_PROPERTY_CATEGORY
);
371 NS_ENSURE_SUCCESS(rv
, rv
);
373 // Initial filling of the has table has been done.
374 // Now, listen for changes.
375 nsCOMPtr
<nsIObserverService
> serv
=
376 mozilla::services::GetObserverService();
379 serv
->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID
, true);
380 serv
->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID
, true);
387 nsScriptNameSpaceManager::LookupNameInternal(const nsAString
& aName
,
388 const char16_t
**aClassName
)
390 GlobalNameMapEntry
*entry
=
391 static_cast<GlobalNameMapEntry
*>
392 (PL_DHashTableOperate(&mGlobalNames
, &aName
,
395 if (PL_DHASH_ENTRY_IS_BUSY(entry
)) {
397 *aClassName
= entry
->mKey
.get();
399 return &entry
->mGlobalName
;
403 *aClassName
= nullptr;
408 const nsGlobalNameStruct
*
409 nsScriptNameSpaceManager::LookupNavigatorName(const nsAString
& aName
)
411 GlobalNameMapEntry
*entry
=
412 static_cast<GlobalNameMapEntry
*>
413 (PL_DHashTableOperate(&mNavigatorNames
, &aName
,
416 if (!PL_DHASH_ENTRY_IS_BUSY(entry
)) {
420 return &entry
->mGlobalName
;
424 nsScriptNameSpaceManager::RegisterClassName(const char *aClassName
,
425 int32_t aDOMClassInfoID
,
428 const char16_t
**aResult
)
430 if (!nsCRT::IsAscii(aClassName
)) {
431 NS_ERROR("Trying to register a non-ASCII class name");
434 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, aClassName
, aResult
);
435 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
437 if (s
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
441 // If a external constructor is already defined with aClassName we
442 // won't overwrite it.
444 if (s
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
) {
448 NS_ASSERTION(s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
449 s
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
||
450 s
->mType
== nsGlobalNameStruct::eTypeInterface
,
451 "Whaaa, JS environment name clash!");
453 s
->mType
= nsGlobalNameStruct::eTypeClassConstructor
;
454 s
->mDOMClassInfoID
= aDOMClassInfoID
;
455 s
->mChromeOnly
= aPrivileged
;
456 s
->mAllowXBL
= aXBLAllowed
;
462 nsScriptNameSpaceManager::RegisterClassProto(const char *aClassName
,
463 const nsIID
*aConstructorProtoIID
,
466 NS_ENSURE_ARG_POINTER(aConstructorProtoIID
);
470 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, aClassName
);
471 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
473 if (s
->mType
!= nsGlobalNameStruct::eTypeNotInitialized
&&
474 s
->mType
!= nsGlobalNameStruct::eTypeNewDOMBinding
&&
475 s
->mType
!= nsGlobalNameStruct::eTypeInterface
) {
481 s
->mType
= nsGlobalNameStruct::eTypeClassProto
;
482 s
->mIID
= *aConstructorProtoIID
;
488 nsScriptNameSpaceManager::RegisterExternalClassName(const char *aClassName
,
491 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, aClassName
);
492 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
494 // If an external constructor is already defined with aClassName we
495 // won't overwrite it.
497 if (s
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
) {
501 NS_ASSERTION(s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
502 s
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
||
503 s
->mType
== nsGlobalNameStruct::eTypeInterface
,
504 "Whaaa, JS environment name clash!");
506 s
->mType
= nsGlobalNameStruct::eTypeExternalClassInfoCreator
;
513 nsScriptNameSpaceManager::RegisterDOMCIData(const char *aName
,
514 nsDOMClassInfoExternalConstructorFnc aConstructorFptr
,
515 const nsIID
*aProtoChainInterface
,
516 const nsIID
**aInterfaces
,
517 uint32_t aScriptableFlags
,
518 bool aHasClassInterface
,
519 const nsCID
*aConstructorCID
)
521 const char16_t
* className
;
522 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, aName
, &className
);
523 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
525 // If an external constructor is already defined with aClassName we
526 // won't overwrite it.
528 if (s
->mType
== nsGlobalNameStruct::eTypeClassConstructor
||
529 s
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
533 // XXX Should we bail out here?
534 NS_ASSERTION(s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
535 s
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
||
536 s
->mType
== nsGlobalNameStruct::eTypeExternalClassInfoCreator
,
537 "Someone tries to register classinfo data for a class that isn't new or external!");
539 s
->mData
= new nsExternalDOMClassInfoData
;
540 NS_ENSURE_TRUE(s
->mData
, NS_ERROR_OUT_OF_MEMORY
);
542 s
->mType
= nsGlobalNameStruct::eTypeExternalClassInfo
;
543 s
->mData
->mName
= aName
;
544 s
->mData
->mNameUTF16
= className
;
545 if (aConstructorFptr
)
546 s
->mData
->u
.mExternalConstructorFptr
= aConstructorFptr
;
548 // null constructor will cause us to use nsDOMGenericSH::doCreate
549 s
->mData
->u
.mExternalConstructorFptr
= nullptr;
550 s
->mData
->mCachedClassInfo
= nullptr;
551 s
->mData
->mProtoChainInterface
= aProtoChainInterface
;
552 s
->mData
->mInterfaces
= aInterfaces
;
553 s
->mData
->mScriptableFlags
= aScriptableFlags
;
554 s
->mData
->mHasClassInterface
= aHasClassInterface
;
555 s
->mData
->mConstructorCID
= aConstructorCID
;
561 nsScriptNameSpaceManager::OperateCategoryEntryHash(nsICategoryManager
* aCategoryManager
,
562 const char* aCategory
,
566 MOZ_ASSERT(aCategoryManager
);
567 // Get the type from the category name.
568 // NOTE: we could have passed the type in FillHash() and guessed it in
569 // Observe() but this way, we have only one place to update and this is
570 // not performance sensitive.
571 nsGlobalNameStruct::nametype type
;
572 if (strcmp(aCategory
, JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY
) == 0) {
573 type
= nsGlobalNameStruct::eTypeExternalConstructor
;
574 } else if (strcmp(aCategory
, JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY
) == 0 ||
575 strcmp(aCategory
, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY
) == 0) {
576 type
= nsGlobalNameStruct::eTypeProperty
;
577 } else if (strcmp(aCategory
, JAVASCRIPT_NAVIGATOR_PROPERTY_CATEGORY
) == 0) {
578 type
= nsGlobalNameStruct::eTypeNavigatorProperty
;
583 nsCOMPtr
<nsISupportsCString
> strWrapper
= do_QueryInterface(aEntry
);
586 NS_WARNING("Category entry not an nsISupportsCString!");
590 nsAutoCString categoryEntry
;
591 nsresult rv
= strWrapper
->GetData(categoryEntry
);
592 NS_ENSURE_SUCCESS(rv
, rv
);
595 if (type
== nsGlobalNameStruct::eTypeNavigatorProperty
) {
596 table
= &mNavigatorNames
;
598 table
= &mGlobalNames
;
601 // We need to handle removal before calling GetCategoryEntry
602 // because the category entry is already removed before we are
605 NS_ConvertASCIItoUTF16
entry(categoryEntry
);
606 const nsGlobalNameStruct
*s
=
607 type
== nsGlobalNameStruct::eTypeNavigatorProperty
?
608 LookupNavigatorName(entry
) : LookupNameInternal(entry
);
609 // Verify mType so that this API doesn't remove names
610 // registered by others.
611 if (!s
|| s
->mType
!= type
) {
615 RemoveFromHash(table
, &entry
);
619 nsXPIDLCString contractId
;
620 rv
= aCategoryManager
->GetCategoryEntry(aCategory
, categoryEntry
.get(),
621 getter_Copies(contractId
));
622 NS_ENSURE_SUCCESS(rv
, rv
);
624 if (type
== nsGlobalNameStruct::eTypeNavigatorProperty
||
625 type
== nsGlobalNameStruct::eTypeExternalConstructor
) {
626 bool isNavProperty
= type
== nsGlobalNameStruct::eTypeNavigatorProperty
;
627 nsPrintfCString
prefName("dom.%s.disable.%s",
628 isNavProperty
? "navigator-property" : "global-constructor",
629 categoryEntry
.get());
630 if (Preferences::GetType(prefName
.get()) == nsIPrefBranch::PREF_BOOL
&&
631 Preferences::GetBool(prefName
.get(), false)) {
636 nsCOMPtr
<nsIComponentRegistrar
> registrar
;
637 rv
= NS_GetComponentRegistrar(getter_AddRefs(registrar
));
638 NS_ENSURE_SUCCESS(rv
, rv
);
641 rv
= registrar
->ContractIDToCID(contractId
, &cidPtr
);
644 NS_WARNING("Bad contract id registed with the script namespace manager");
648 // Copy CID onto the stack, so we can free it right away and avoid having
649 // to add cleanup code at every exit point from this function.
651 nsMemory::Free(cidPtr
);
653 if (type
== nsGlobalNameStruct::eTypeExternalConstructor
) {
654 nsXPIDLCString constructorProto
;
655 rv
= aCategoryManager
->GetCategoryEntry(JAVASCRIPT_GLOBAL_CONSTRUCTOR_PROTO_ALIAS_CATEGORY
,
657 getter_Copies(constructorProto
));
658 if (NS_SUCCEEDED(rv
)) {
659 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, categoryEntry
.get());
660 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
662 if (s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
663 s
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
) {
664 s
->mAlias
= new nsGlobalNameStruct::ConstructorAlias
;
665 s
->mType
= nsGlobalNameStruct::eTypeExternalConstructorAlias
;
666 s
->mChromeOnly
= false;
667 s
->mAlias
->mCID
= cid
;
668 AppendASCIItoUTF16(constructorProto
, s
->mAlias
->mProtoName
);
669 s
->mAlias
->mProto
= nullptr;
671 NS_WARNING("Global script name not overwritten!");
678 nsGlobalNameStruct
*s
= AddToHash(table
, categoryEntry
.get());
679 NS_ENSURE_TRUE(s
, NS_ERROR_OUT_OF_MEMORY
);
681 if (s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
||
682 s
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
) {
686 strcmp(aCategory
, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY
) == 0;
688 NS_WARNING("Global script name not overwritten!");
695 nsScriptNameSpaceManager::AddCategoryEntryToHash(nsICategoryManager
* aCategoryManager
,
696 const char* aCategory
,
699 return OperateCategoryEntryHash(aCategoryManager
, aCategory
, aEntry
,
700 /* aRemove = */ false);
704 nsScriptNameSpaceManager::RemoveCategoryEntryFromHash(nsICategoryManager
* aCategoryManager
,
705 const char* aCategory
,
708 return OperateCategoryEntryHash(aCategoryManager
, aCategory
, aEntry
,
709 /* aRemove = */ true);
713 nsScriptNameSpaceManager::Observe(nsISupports
* aSubject
, const char* aTopic
,
714 const char16_t
* aData
)
720 if (!strcmp(aTopic
, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID
)) {
721 nsCOMPtr
<nsICategoryManager
> cm
=
722 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
);
727 return AddCategoryEntryToHash(cm
, NS_ConvertUTF16toUTF8(aData
).get(),
729 } else if (!strcmp(aTopic
, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID
)) {
730 nsCOMPtr
<nsICategoryManager
> cm
=
731 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
);
736 return RemoveCategoryEntryFromHash(cm
, NS_ConvertUTF16toUTF8(aData
).get(),
740 // TODO: we could observe NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID
741 // but we are safe without it. See bug 600460.
747 nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString
& aName
,
748 mozilla::dom::DefineInterface aDefineDOMInterface
,
749 mozilla::dom::ConstructorEnabled
* aConstructorEnabled
)
751 nsGlobalNameStruct
*s
= AddToHash(&mGlobalNames
, &aName
);
753 if (s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
) {
754 s
->mType
= nsGlobalNameStruct::eTypeNewDOMBinding
;
756 s
->mDefineDOMInterface
= aDefineDOMInterface
;
757 s
->mConstructorEnabled
= aConstructorEnabled
;
762 nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
763 const nsAFlatString
& aName
,
764 mozilla::dom::ConstructNavigatorProperty aNavConstructor
,
765 mozilla::dom::ConstructorEnabled
* aConstructorEnabled
)
767 nsGlobalNameStruct
*s
= AddToHash(&mNavigatorNames
, &aName
);
769 if (s
->mType
== nsGlobalNameStruct::eTypeNotInitialized
) {
770 s
->mType
= nsGlobalNameStruct::eTypeNewDOMBinding
;
772 s
->mConstructNavigatorProperty
= aNavConstructor
;
773 s
->mConstructorEnabled
= aConstructorEnabled
;
779 nsScriptNameSpaceManager::NameEnumerator enumerator
;
783 static PLDHashOperator
784 EnumerateName(PLDHashTable
*, PLDHashEntryHdr
*hdr
, uint32_t, void* aClosure
)
786 GlobalNameMapEntry
*entry
= static_cast<GlobalNameMapEntry
*>(hdr
);
787 NameClosure
* closure
= static_cast<NameClosure
*>(aClosure
);
788 return closure
->enumerator(entry
->mKey
, entry
->mGlobalName
, closure
->closure
);
792 nsScriptNameSpaceManager::EnumerateGlobalNames(NameEnumerator aEnumerator
,
795 NameClosure closure
= { aEnumerator
, aClosure
};
796 PL_DHashTableEnumerate(&mGlobalNames
, EnumerateName
, &closure
);
800 nsScriptNameSpaceManager::EnumerateNavigatorNames(NameEnumerator aEnumerator
,
803 NameClosure closure
= { aEnumerator
, aClosure
};
804 PL_DHashTableEnumerate(&mNavigatorNames
, EnumerateName
, &closure
);
808 SizeOfEntryExcludingThis(PLDHashEntryHdr
*aHdr
, MallocSizeOf aMallocSizeOf
,
811 GlobalNameMapEntry
* entry
= static_cast<GlobalNameMapEntry
*>(aHdr
);
812 return entry
->SizeOfExcludingThis(aMallocSizeOf
);
815 MOZ_DEFINE_MALLOC_SIZE_OF(ScriptNameSpaceManagerMallocSizeOf
)
818 nsScriptNameSpaceManager::CollectReports(
819 nsIHandleReportCallback
* aHandleReport
, nsISupports
* aData
, bool aAnonymize
)
821 return MOZ_COLLECT_REPORT(
822 "explicit/script-namespace-manager", KIND_HEAP
, UNITS_BYTES
,
823 SizeOfIncludingThis(ScriptNameSpaceManagerMallocSizeOf
),
824 "Memory used for the script namespace manager.");
828 nsScriptNameSpaceManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
)
831 n
+= PL_DHashTableSizeOfExcludingThis(&mGlobalNames
,
832 SizeOfEntryExcludingThis
, aMallocSizeOf
);
833 n
+= PL_DHashTableSizeOfExcludingThis(&mNavigatorNames
,
834 SizeOfEntryExcludingThis
, aMallocSizeOf
);