1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=78: */
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 "mozilla/ArrayUtils.h"
13 // JavaScript includes
15 #include "jsfriendapi.h"
16 #include "WrapperFactory.h"
17 #include "AccessCheck.h"
18 #include "XrayWrapper.h"
20 #include "xpcpublic.h"
21 #include "xpcprivate.h"
22 #include "XPCWrapper.h"
24 #include "mozilla/DOMEventTargetHelper.h"
25 #include "mozilla/dom/RegisterBindings.h"
28 #include "nsDOMClassInfo.h"
30 #include "nsCRTGlue.h"
31 #include "nsICategoryManager.h"
32 #include "nsIComponentRegistrar.h"
34 #include "nsISupportsPrimitives.h"
35 #include "nsIXPConnect.h"
38 #include "nsDocument.h" // nsDOMStyleSheetList
39 #include "nsDOMBlobBuilder.h"
41 // General helper includes
42 #include "nsGlobalWindow.h"
43 #include "nsIContent.h"
44 #include "nsIDocument.h"
45 #include "nsIDOMDocument.h"
46 #include "nsIDOMEvent.h"
47 #include "nsIDOMEventListener.h"
48 #include "nsContentUtils.h"
49 #include "nsIDOMGlobalPropertyInitializer.h"
50 #include "mozilla/Attributes.h"
51 #include "mozilla/Telemetry.h"
53 // Window scriptable helper includes
54 #include "nsIDocShell.h"
55 #include "nsJSUtils.h"
56 #include "nsScriptNameSpaceManager.h"
57 #include "nsIJSNativeInitializer.h"
58 #include "nsJSEnvironment.h"
61 #include "nsIDOMLocation.h"
62 #include "nsIDOMWindow.h"
63 #include "nsPIDOMWindow.h"
64 #include "nsIDOMJSWindow.h"
65 #include "nsIDOMChromeWindow.h"
66 #include "nsIDOMConstructor.h"
70 #include "nsIDOMUserDataHandler.h"
71 #include "nsIDOMXULButtonElement.h"
72 #include "nsIDOMXULCheckboxElement.h"
73 #include "nsIDOMXULPopupElement.h"
75 // Event related includes
76 #include "nsIDOMEventTarget.h"
78 // CSS related includes
79 #include "nsCSSRules.h"
80 #include "nsIDOMCSSRule.h"
81 #include "nsAutoPtr.h"
85 #include "nsIXSLTProcessor.h"
86 #include "nsIXSLTProcessorPrivate.h"
88 // includes needed for the prototype chain interfaces
89 #include "nsIDOMCSSCharsetRule.h"
90 #include "nsIDOMCSSImportRule.h"
91 #include "nsIDOMCSSMediaRule.h"
92 #include "nsIDOMCSSFontFaceRule.h"
93 #include "nsIDOMCSSMozDocumentRule.h"
94 #include "nsIDOMCSSSupportsRule.h"
95 #include "nsIDOMMozCSSKeyframeRule.h"
96 #include "nsIDOMMozCSSKeyframesRule.h"
97 #include "nsIDOMCSSCounterStyleRule.h"
98 #include "nsIDOMCSSPageRule.h"
99 #include "nsIDOMCSSStyleRule.h"
100 #include "nsIDOMXULCommandDispatcher.h"
101 #include "nsIControllers.h"
102 #include "nsIBoxObject.h"
104 #include "nsITreeSelection.h"
105 #include "nsITreeContentView.h"
106 #include "nsITreeView.h"
107 #include "nsIXULTemplateBuilder.h"
108 #include "nsITreeColumns.h"
110 #include "nsIDOMXPathNSResolver.h"
113 #include "nsIDOMFile.h"
114 #include "nsDOMBlobBuilder.h" // nsDOMMultipartFile
116 #include "nsIEventListenerService.h"
117 #include "nsIMessageManager.h"
119 #include "mozilla/dom/TouchEvent.h"
121 #include "nsWrapperCacheInlines.h"
122 #include "mozilla/dom/HTMLCollectionBinding.h"
124 #include "nsIDOMMozSmsMessage.h"
125 #include "nsIDOMMozMmsMessage.h"
126 #include "nsIDOMMozMobileMessageThread.h"
132 #include "nsIDOMGlobalObjectConstructor.h"
135 #include "mozilla/dom/BindingUtils.h"
136 #include "mozilla/Likely.h"
137 #include "WindowNamedPropertiesHandler.h"
138 #include "nsIInterfaceInfoManager.h"
139 #include "mozilla/dom/EventTargetBinding.h"
140 #include "mozilla/dom/WindowBinding.h"
142 #ifdef MOZ_TIME_MANAGER
143 #include "TimeManager.h"
146 using namespace mozilla
;
147 using namespace mozilla::dom
;
149 static NS_DEFINE_CID(kDOMSOF_CID
, NS_DOM_SCRIPT_OBJECT_FACTORY_CID
);
151 // NOTE: DEFAULT_SCRIPTABLE_FLAGS and DOM_DEFAULT_SCRIPTABLE_FLAGS
152 // are defined in nsIDOMClassInfo.h.
154 #define WINDOW_SCRIPTABLE_FLAGS \
155 (nsIXPCScriptable::WANT_PRECREATE | \
156 nsIXPCScriptable::WANT_POSTCREATE | \
157 nsIXPCScriptable::WANT_ENUMERATE | \
158 nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
159 nsIXPCScriptable::IS_GLOBAL_OBJECT | \
160 nsIXPCScriptable::WANT_OUTER_OBJECT)
162 #define ARRAY_SCRIPTABLE_FLAGS \
163 (DOM_DEFAULT_SCRIPTABLE_FLAGS | \
164 nsIXPCScriptable::WANT_GETPROPERTY | \
165 nsIXPCScriptable::WANT_ENUMERATE)
167 #define EVENTTARGET_SCRIPTABLE_FLAGS \
168 (DOM_DEFAULT_SCRIPTABLE_FLAGS | \
169 nsIXPCScriptable::WANT_ADDPROPERTY)
171 #define DOMCLASSINFO_STANDARD_FLAGS \
172 (nsIClassInfo::MAIN_THREAD_ONLY | \
173 nsIClassInfo::DOM_OBJECT | \
174 nsIClassInfo::SINGLETON_CLASSINFO)
178 #define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
179 eDOMClassInfo_##_class##_id,
181 #define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
186 * To generate the bitmap for a class that we're sure doesn't implement any of
187 * the interfaces in DOMCI_CASTABLE_INTERFACES.
189 #define DOMCI_DATA_NO_CLASS(_dom_class) \
190 const uint32_t kDOMClassInfo_##_dom_class##_interfaces = \
193 DOMCI_DATA_NO_CLASS(ContentFrameMessageManager
)
194 DOMCI_DATA_NO_CLASS(ChromeMessageBroadcaster
)
195 DOMCI_DATA_NO_CLASS(ChromeMessageSender
)
197 DOMCI_DATA_NO_CLASS(DOMPrototype
)
198 DOMCI_DATA_NO_CLASS(DOMConstructor
)
200 DOMCI_DATA_NO_CLASS(UserDataHandler
)
201 DOMCI_DATA_NO_CLASS(XULControlElement
)
202 DOMCI_DATA_NO_CLASS(XULLabeledControlElement
)
203 DOMCI_DATA_NO_CLASS(XULButtonElement
)
204 DOMCI_DATA_NO_CLASS(XULCheckboxElement
)
205 DOMCI_DATA_NO_CLASS(XULPopupElement
)
207 #define NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, \
208 _chromeOnly, _allowXBL) \
211 { _helper::doCreate }, \
221 NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
224 #define NS_DEFINE_CLASSINFO_DATA(_class, _helper, _flags) \
225 NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, false, false)
227 #define NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(_class, _helper, _flags) \
228 NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, true, false)
230 #define NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(_class, _helper, _flags) \
231 NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, true, true)
234 // This list of NS_DEFINE_CLASSINFO_DATA macros is what gives the DOM
235 // classes their correct behavior when used through XPConnect. The
236 // arguments that are passed to NS_DEFINE_CLASSINFO_DATA are
238 // 1. Class name as it should appear in JavaScript, this name is also
239 // used to find the id of the class in nsDOMClassInfo
240 // (i.e. e<classname>_id)
241 // 2. Scriptable helper class
242 // 3. nsIClassInfo/nsIXPCScriptable flags (i.e. for GetScriptableFlags)
244 static nsDOMClassInfoData sClassInfoData
[] = {
247 // The Window class lets you QI into interfaces that are not in the
248 // flattened set (i.e. nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY
249 // is not set), because of this make sure all scriptable interfaces
250 // that are implemented by nsGlobalWindow can securely be exposed
254 NS_DEFINE_CLASSINFO_DATA(Window
, nsWindowSH
,
255 DEFAULT_SCRIPTABLE_FLAGS
|
256 WINDOW_SCRIPTABLE_FLAGS
)
258 NS_DEFINE_CLASSINFO_DATA(DOMPrototype
, nsDOMConstructorSH
,
259 DOM_BASE_SCRIPTABLE_FLAGS
|
260 nsIXPCScriptable::WANT_PRECREATE
|
261 nsIXPCScriptable::WANT_NEWRESOLVE
|
262 nsIXPCScriptable::WANT_HASINSTANCE
|
263 nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE
)
264 NS_DEFINE_CLASSINFO_DATA(DOMConstructor
, nsDOMConstructorSH
,
265 DOM_BASE_SCRIPTABLE_FLAGS
|
266 nsIXPCScriptable::WANT_PRECREATE
|
267 nsIXPCScriptable::WANT_NEWRESOLVE
|
268 nsIXPCScriptable::WANT_HASINSTANCE
|
269 nsIXPCScriptable::WANT_CALL
|
270 nsIXPCScriptable::WANT_CONSTRUCT
|
271 nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE
)
273 // Misc Core related classes
276 NS_DEFINE_CLASSINFO_DATA(CSSStyleRule
, nsDOMGenericSH
,
277 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
278 NS_DEFINE_CLASSINFO_DATA(CSSCharsetRule
, nsDOMGenericSH
,
279 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
280 NS_DEFINE_CLASSINFO_DATA(CSSImportRule
, nsDOMGenericSH
,
281 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
282 NS_DEFINE_CLASSINFO_DATA(CSSMediaRule
, nsDOMGenericSH
,
283 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
284 NS_DEFINE_CLASSINFO_DATA(CSSNameSpaceRule
, nsDOMGenericSH
,
285 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
289 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCommandDispatcher
, nsDOMGenericSH
,
290 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
292 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControllers
, nsNonDOMObjectSH
,
293 DEFAULT_SCRIPTABLE_FLAGS
)
294 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(BoxObject
, nsDOMGenericSH
,
295 DEFAULT_SCRIPTABLE_FLAGS
)
297 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(TreeSelection
, nsDOMGenericSH
,
298 DEFAULT_SCRIPTABLE_FLAGS
)
299 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(TreeContentView
, nsDOMGenericSH
,
300 DEFAULT_SCRIPTABLE_FLAGS
)
303 // DOM Chrome Window class.
304 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(ChromeWindow
, nsWindowSH
,
305 DEFAULT_SCRIPTABLE_FLAGS
|
306 WINDOW_SCRIPTABLE_FLAGS
)
309 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTemplateBuilder
, nsDOMGenericSH
,
310 DEFAULT_SCRIPTABLE_FLAGS
)
312 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTreeBuilder
, nsDOMGenericSH
,
313 DEFAULT_SCRIPTABLE_FLAGS
)
317 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(TreeColumn
, nsDOMGenericSH
,
318 DEFAULT_SCRIPTABLE_FLAGS
)
321 NS_DEFINE_CLASSINFO_DATA(CSSMozDocumentRule
, nsDOMGenericSH
,
322 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
324 NS_DEFINE_CLASSINFO_DATA(CSSSupportsRule
, nsDOMGenericSH
,
325 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
327 NS_DEFINE_CLASSINFO_DATA(XSLTProcessor
, nsDOMGenericSH
,
328 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
330 NS_DEFINE_CLASSINFO_DATA(XPathNSResolver
, nsDOMGenericSH
,
331 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
333 NS_DEFINE_CLASSINFO_DATA(Blob
, nsDOMGenericSH
,
334 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
335 NS_DEFINE_CLASSINFO_DATA(File
, nsDOMGenericSH
,
336 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
338 NS_DEFINE_CLASSINFO_DATA(ModalContentWindow
, nsWindowSH
,
339 DEFAULT_SCRIPTABLE_FLAGS
|
340 WINDOW_SCRIPTABLE_FLAGS
)
342 NS_DEFINE_CLASSINFO_DATA(MozSmsMessage
, nsDOMGenericSH
,
343 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
345 NS_DEFINE_CLASSINFO_DATA(MozMmsMessage
, nsDOMGenericSH
,
346 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
348 NS_DEFINE_CLASSINFO_DATA(MozMobileMessageThread
, nsDOMGenericSH
,
349 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
351 NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule
, nsDOMGenericSH
,
352 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
354 NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager
, nsEventTargetSH
,
355 DOM_DEFAULT_SCRIPTABLE_FLAGS
|
356 nsIXPCScriptable::IS_GLOBAL_OBJECT
)
357 NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster
, nsDOMGenericSH
,
358 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
359 NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender
, nsDOMGenericSH
,
360 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
363 NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframeRule
, nsDOMGenericSH
,
364 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
365 NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule
, nsDOMGenericSH
,
366 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
368 NS_DEFINE_CLASSINFO_DATA(CSSCounterStyleRule
, nsDOMGenericSH
,
369 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
371 NS_DEFINE_CLASSINFO_DATA(CSSPageRule
, nsDOMGenericSH
,
372 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
374 NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule
, nsDOMGenericSH
,
375 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
377 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(UserDataHandler
, nsDOMGenericSH
,
378 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
379 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement
, nsDOMGenericSH
,
380 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
381 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULLabeledControlElement
, nsDOMGenericSH
,
382 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
383 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULButtonElement
, nsDOMGenericSH
,
384 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
385 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCheckboxElement
, nsDOMGenericSH
,
386 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
387 NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULPopupElement
, nsDOMGenericSH
,
388 DOM_DEFAULT_SCRIPTABLE_FLAGS
)
391 #define NS_DEFINE_CONTRACT_CTOR(_class, _contract_id) \
393 _class##Ctor(nsISupports** aInstancePtrResult) \
395 nsresult rv = NS_OK; \
396 nsCOMPtr<nsISupports> native = do_CreateInstance(_contract_id, &rv); \
397 native.forget(aInstancePtrResult); \
401 NS_DEFINE_CONTRACT_CTOR(XSLTProcessor
,
402 "@mozilla.org/document-transformer;1?type=xslt")
404 #undef NS_DEFINE_CONTRACT_CTOR
406 struct nsConstructorFuncMapData
408 int32_t mDOMClassInfoID
;
409 nsDOMConstructorFunc mConstructorFunc
;
412 #define NS_DEFINE_CONSTRUCTOR_FUNC_DATA(_class, _func) \
413 { eDOMClassInfo_##_class##_id, _func },
415 static const nsConstructorFuncMapData kConstructorFuncMap
[] =
417 NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Blob
, DOMMultipartFileImpl::NewBlob
)
418 NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File
, DOMMultipartFileImpl::NewFile
)
419 NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XSLTProcessor
, XSLTProcessorCtor
)
421 #undef NS_DEFINE_CONSTRUCTOR_FUNC_DATA
423 nsIXPConnect
*nsDOMClassInfo::sXPConnect
= nullptr;
424 bool nsDOMClassInfo::sIsInitialized
= false;
427 jsid
nsDOMClassInfo::sLocation_id
= JSID_VOID
;
428 jsid
nsDOMClassInfo::sConstructor_id
= JSID_VOID
;
429 jsid
nsDOMClassInfo::sTop_id
= JSID_VOID
;
430 jsid
nsDOMClassInfo::sDocument_id
= JSID_VOID
;
431 jsid
nsDOMClassInfo::sWrappedJSObject_id
= JSID_VOID
;
433 static const JSClass
*sObjectClass
= nullptr;
436 * Set our JSClass pointer for the Object class
439 FindObjectClass(JSContext
* cx
, JSObject
* aGlobalObject
)
441 NS_ASSERTION(!sObjectClass
,
442 "Double set of sObjectClass");
443 JS::Rooted
<JSObject
*> obj(cx
), proto(cx
, aGlobalObject
);
446 js::GetObjectProto(cx
, obj
, &proto
);
449 sObjectClass
= js::GetObjectJSClass(obj
);
452 static inline nsresult
453 WrapNative(JSContext
*cx
, nsISupports
*native
,
454 nsWrapperCache
*cache
, const nsIID
* aIID
, JS::MutableHandle
<JS::Value
> vp
,
463 JSObject
*wrapper
= xpc_FastGetCachedWrapper(cx
, cache
, vp
);
468 JS::Rooted
<JSObject
*> scope(cx
, JS::CurrentGlobalOrNull(cx
));
469 return nsDOMClassInfo::XPConnect()->WrapNativeToJSVal(cx
, scope
, native
,
474 static inline nsresult
475 WrapNative(JSContext
*cx
, nsISupports
*native
, const nsIID
* aIID
,
476 bool aAllowWrapping
, JS::MutableHandle
<JS::Value
> vp
)
478 return WrapNative(cx
, native
, nullptr, aIID
, vp
, aAllowWrapping
);
481 // Same as the WrapNative above, but use these if aIID is nsISupports' IID.
482 static inline nsresult
483 WrapNative(JSContext
*cx
, nsISupports
*native
,
484 bool aAllowWrapping
, JS::MutableHandle
<JS::Value
> vp
)
486 return WrapNative(cx
, native
, nullptr, nullptr, vp
, aAllowWrapping
);
489 // Helper to handle torn-down inner windows.
490 static inline nsresult
491 SetParentToWindow(nsGlobalWindow
*win
, JSObject
**parent
)
494 MOZ_ASSERT(win
->IsInnerWindow());
495 *parent
= win
->FastGetGlobalJSObject();
497 if (MOZ_UNLIKELY(!*parent
)) {
498 // The inner window has been torn down. The scope is dying, so don't create
500 return NS_ERROR_FAILURE
;
508 nsDOMClassInfo::GetNative(nsIXPConnectWrappedNative
*wrapper
, JSObject
*obj
)
510 return wrapper
? wrapper
->Native() : static_cast<nsISupports
*>(js::GetObjectPrivate(obj
));
514 nsDOMClassInfo::DefineStaticJSVals(JSContext
*cx
)
516 #define SET_JSID_TO_STRING(_id, _cx, _str) \
517 if (JSString *str = ::JS_InternString(_cx, _str)) \
518 _id = INTERNED_STRING_TO_JSID(_cx, str); \
520 return NS_ERROR_OUT_OF_MEMORY;
522 SET_JSID_TO_STRING(sLocation_id
, cx
, "location");
523 SET_JSID_TO_STRING(sConstructor_id
, cx
, "constructor");
524 SET_JSID_TO_STRING(sTop_id
, cx
, "top");
525 SET_JSID_TO_STRING(sDocument_id
, cx
, "document");
526 SET_JSID_TO_STRING(sWrappedJSObject_id
, cx
, "wrappedJSObject");
533 nsDOMClassInfo::ObjectIsNativeWrapper(JSContext
* cx
, JSObject
* obj
)
535 return xpc::WrapperFactory::IsXrayWrapper(obj
) &&
536 xpc::AccessCheck::wrapperSubsumes(obj
);
539 nsDOMClassInfo::nsDOMClassInfo(nsDOMClassInfoData
* aData
) : mData(aData
)
543 nsDOMClassInfo::~nsDOMClassInfo()
545 if (IS_EXTERNAL(mData
->mCachedClassInfo
)) {
546 // Some compilers don't like delete'ing a const nsDOMClassInfo*
547 nsDOMClassInfoData
* data
= const_cast<nsDOMClassInfoData
*>(mData
);
548 delete static_cast<nsExternalDOMClassInfoData
*>(data
);
552 NS_IMPL_ADDREF(nsDOMClassInfo
)
553 NS_IMPL_RELEASE(nsDOMClassInfo
)
555 NS_INTERFACE_MAP_BEGIN(nsDOMClassInfo
)
556 if (aIID
.Equals(NS_GET_IID(nsXPCClassInfo
)))
557 foundInterface
= static_cast<nsIClassInfo
*>(
558 static_cast<nsXPCClassInfo
*>(this));
560 NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable
)
561 NS_INTERFACE_MAP_ENTRY(nsIClassInfo
)
562 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIClassInfo
)
566 static const JSClass sDOMConstructorProtoClass
= {
567 "DOM Constructor.prototype", 0,
568 JS_PropertyStub
, JS_DeletePropertyStub
, JS_PropertyStub
, JS_StrictPropertyStub
,
569 JS_EnumerateStub
, JS_ResolveStub
, JS_ConvertStub
, nullptr
574 CutPrefix(const char *aName
) {
575 static const char prefix_nsIDOM
[] = "nsIDOM";
576 static const char prefix_nsI
[] = "nsI";
578 if (strncmp(aName
, prefix_nsIDOM
, sizeof(prefix_nsIDOM
) - 1) == 0) {
579 return aName
+ sizeof(prefix_nsIDOM
) - 1;
582 if (strncmp(aName
, prefix_nsI
, sizeof(prefix_nsI
) - 1) == 0) {
583 return aName
+ sizeof(prefix_nsI
) - 1;
591 nsDOMClassInfo::RegisterClassProtos(int32_t aClassInfoID
)
593 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
594 NS_ENSURE_TRUE(nameSpaceManager
, NS_ERROR_NOT_INITIALIZED
);
597 const nsIID
*primary_iid
= sClassInfoData
[aClassInfoID
].mProtoChainInterface
;
599 if (!primary_iid
|| primary_iid
== &NS_GET_IID(nsISupports
)) {
603 nsCOMPtr
<nsIInterfaceInfoManager
>
604 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
605 NS_ENSURE_TRUE(iim
, NS_ERROR_NOT_AVAILABLE
);
607 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
610 iim
->GetInfoForIID(primary_iid
, getter_AddRefs(if_info
));
613 const nsIID
*iid
= nullptr;
615 if_info
->GetIIDShared(&iid
);
616 NS_ENSURE_TRUE(iid
, NS_ERROR_UNEXPECTED
);
618 if (iid
->Equals(NS_GET_IID(nsISupports
))) {
622 const char *name
= nullptr;
623 if_info
->GetNameShared(&name
);
624 NS_ENSURE_TRUE(name
, NS_ERROR_UNEXPECTED
);
626 nameSpaceManager
->RegisterClassProto(CutPrefix(name
), iid
, &found_old
);
630 } else if (found_old
) {
634 nsCOMPtr
<nsIInterfaceInfo
> tmp(if_info
);
635 tmp
->GetParent(getter_AddRefs(if_info
));
643 nsDOMClassInfo::RegisterExternalClasses()
645 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
646 NS_ENSURE_TRUE(nameSpaceManager
, NS_ERROR_NOT_INITIALIZED
);
648 nsCOMPtr
<nsIComponentRegistrar
> registrar
;
649 nsresult rv
= NS_GetComponentRegistrar(getter_AddRefs(registrar
));
650 NS_ENSURE_SUCCESS(rv
, rv
);
652 nsCOMPtr
<nsICategoryManager
> cm
=
653 do_GetService(NS_CATEGORYMANAGER_CONTRACTID
, &rv
);
654 NS_ENSURE_SUCCESS(rv
, rv
);
656 nsCOMPtr
<nsISimpleEnumerator
> e
;
657 rv
= cm
->EnumerateCategory(JAVASCRIPT_DOM_CLASS
, getter_AddRefs(e
));
658 NS_ENSURE_SUCCESS(rv
, rv
);
660 nsXPIDLCString contractId
;
661 nsAutoCString categoryEntry
;
662 nsCOMPtr
<nsISupports
> entry
;
664 while (NS_SUCCEEDED(e
->GetNext(getter_AddRefs(entry
)))) {
665 nsCOMPtr
<nsISupportsCString
> category(do_QueryInterface(entry
));
668 NS_WARNING("Category entry not an nsISupportsCString!");
672 rv
= category
->GetData(categoryEntry
);
674 cm
->GetCategoryEntry(JAVASCRIPT_DOM_CLASS
, categoryEntry
.get(),
675 getter_Copies(contractId
));
676 NS_ENSURE_SUCCESS(rv
, rv
);
679 rv
= registrar
->ContractIDToCID(contractId
, &cid
);
681 NS_WARNING("Bad contract id registered with the script namespace manager");
685 rv
= nameSpaceManager
->RegisterExternalClassName(categoryEntry
.get(), *cid
);
687 NS_ENSURE_SUCCESS(rv
, rv
);
690 return nameSpaceManager
->RegisterExternalInterfaces(true);
693 #define _DOM_CLASSINFO_MAP_BEGIN(_class, _ifptr, _has_class_if) \
695 nsDOMClassInfoData &d = sClassInfoData[eDOMClassInfo_##_class##_id]; \
696 d.mProtoChainInterface = _ifptr; \
697 d.mHasClassInterface = _has_class_if; \
698 d.mInterfacesBitmap = kDOMClassInfo_##_class##_interfaces; \
699 static const nsIID *interface_list[] = {
701 #define DOM_CLASSINFO_MAP_BEGIN(_class, _interface) \
702 _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), true)
704 #define DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(_class, _interface) \
705 _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), false)
707 #define DOM_CLASSINFO_MAP_ENTRY(_if) \
710 #define DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(_if, _cond) \
711 (_cond) ? &NS_GET_IID(_if) : nullptr,
713 #define DOM_CLASSINFO_MAP_END \
717 /* Compact the interface list */ \
718 size_t count = ArrayLength(interface_list); \
719 /* count is the number of array entries, which is one greater than the */ \
720 /* number of interfaces due to the terminating null */ \
721 for (size_t i = 0; i < count - 1; ++i) { \
722 if (!interface_list[i]) { \
723 /* We are moving the element at index i+1 and successors, */ \
724 /* so we must move only count - (i+1) elements total. */ \
725 memmove(&interface_list[i], &interface_list[i+1], \
726 sizeof(nsIID*) * (count - (i+1))); \
727 /* Make sure to examine the new pointer we ended up with at this */ \
728 /* slot, since it may be null too */ \
734 d.mInterfaces = interface_list; \
738 #define DOM_CLASSINFO_WINDOW_MAP_ENTRIES \
739 DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
740 DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowB2G) \
741 DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
742 DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
743 DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
744 DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowPerformance) \
745 DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor) \
746 DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
747 TouchEvent::PrefEnabled())
749 #define DOM_CLASSINFO_WINDOW_MAP_ENTRIES \
750 DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
751 DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
752 DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
753 DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
754 DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowPerformance) \
755 DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor) \
756 DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
757 TouchEvent::PrefEnabled())
761 nsDOMClassInfo::Init()
763 /* Errors that can trigger early returns are done first,
764 otherwise nsDOMClassInfo is left in a half inited state. */
765 static_assert(sizeof(uintptr_t) == sizeof(void*),
766 "BAD! You'll need to adjust the size of uintptr_t to the "
767 "size of a pointer on your platform.");
769 NS_ENSURE_TRUE(!sIsInitialized
, NS_ERROR_ALREADY_INITIALIZED
);
771 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
772 NS_ENSURE_TRUE(nameSpaceManager
, NS_ERROR_NOT_INITIALIZED
);
774 NS_ADDREF(sXPConnect
= nsContentUtils::XPConnect());
776 nsCOMPtr
<nsIXPCFunctionThisTranslator
> elt
= new nsEventListenerThisTranslator();
777 sXPConnect
->SetFunctionThisTranslator(NS_GET_IID(nsIDOMEventListener
), elt
);
779 AutoSafeJSContext cx
;
781 DOM_CLASSINFO_MAP_BEGIN(Window
, nsIDOMWindow
)
782 DOM_CLASSINFO_WINDOW_MAP_ENTRIES
784 DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter
)
786 DOM_CLASSINFO_MAP_END
788 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMPrototype
, nsIDOMDOMConstructor
)
789 DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor
)
790 DOM_CLASSINFO_MAP_END
792 DOM_CLASSINFO_MAP_BEGIN(DOMConstructor
, nsIDOMDOMConstructor
)
793 DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor
)
794 DOM_CLASSINFO_MAP_END
796 DOM_CLASSINFO_MAP_BEGIN(CSSStyleRule
, nsIDOMCSSStyleRule
)
797 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleRule
)
798 DOM_CLASSINFO_MAP_END
800 DOM_CLASSINFO_MAP_BEGIN(CSSCharsetRule
, nsIDOMCSSCharsetRule
)
801 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSCharsetRule
)
802 DOM_CLASSINFO_MAP_END
804 DOM_CLASSINFO_MAP_BEGIN(CSSImportRule
, nsIDOMCSSImportRule
)
805 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSImportRule
)
806 DOM_CLASSINFO_MAP_END
808 DOM_CLASSINFO_MAP_BEGIN(CSSMediaRule
, nsIDOMCSSMediaRule
)
809 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSMediaRule
)
810 DOM_CLASSINFO_MAP_END
812 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSNameSpaceRule
, nsIDOMCSSRule
)
813 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSRule
)
814 DOM_CLASSINFO_MAP_END
817 DOM_CLASSINFO_MAP_BEGIN(XULCommandDispatcher
, nsIDOMXULCommandDispatcher
)
818 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULCommandDispatcher
)
819 DOM_CLASSINFO_MAP_END
822 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControllers
, nsIControllers
)
823 DOM_CLASSINFO_MAP_ENTRY(nsIControllers
)
824 DOM_CLASSINFO_MAP_END
826 DOM_CLASSINFO_MAP_BEGIN(BoxObject
, nsIBoxObject
)
827 DOM_CLASSINFO_MAP_ENTRY(nsIBoxObject
)
828 DOM_CLASSINFO_MAP_END
831 DOM_CLASSINFO_MAP_BEGIN(TreeSelection
, nsITreeSelection
)
832 DOM_CLASSINFO_MAP_ENTRY(nsITreeSelection
)
833 DOM_CLASSINFO_MAP_END
835 DOM_CLASSINFO_MAP_BEGIN(TreeContentView
, nsITreeContentView
)
836 DOM_CLASSINFO_MAP_ENTRY(nsITreeContentView
)
837 DOM_CLASSINFO_MAP_ENTRY(nsITreeView
)
838 DOM_CLASSINFO_MAP_END
841 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeWindow
, nsIDOMWindow
)
842 DOM_CLASSINFO_WINDOW_MAP_ENTRIES
843 DOM_CLASSINFO_MAP_ENTRY(nsIDOMChromeWindow
)
845 DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter
)
847 DOM_CLASSINFO_MAP_END
850 DOM_CLASSINFO_MAP_BEGIN(XULTemplateBuilder
, nsIXULTemplateBuilder
)
851 DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder
)
852 DOM_CLASSINFO_MAP_END
854 DOM_CLASSINFO_MAP_BEGIN(XULTreeBuilder
, nsIXULTreeBuilder
)
855 DOM_CLASSINFO_MAP_ENTRY(nsIXULTreeBuilder
)
856 DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder
)
857 DOM_CLASSINFO_MAP_ENTRY(nsITreeView
)
858 DOM_CLASSINFO_MAP_END
862 DOM_CLASSINFO_MAP_BEGIN(TreeColumn
, nsITreeColumn
)
863 DOM_CLASSINFO_MAP_ENTRY(nsITreeColumn
)
864 DOM_CLASSINFO_MAP_END
867 DOM_CLASSINFO_MAP_BEGIN(CSSMozDocumentRule
, nsIDOMCSSMozDocumentRule
)
868 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSMozDocumentRule
)
869 DOM_CLASSINFO_MAP_END
871 DOM_CLASSINFO_MAP_BEGIN(CSSSupportsRule
, nsIDOMCSSSupportsRule
)
872 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSSupportsRule
)
873 DOM_CLASSINFO_MAP_END
875 DOM_CLASSINFO_MAP_BEGIN(XSLTProcessor
, nsIXSLTProcessor
)
876 DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessor
)
877 DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessorPrivate
)
878 DOM_CLASSINFO_MAP_END
880 DOM_CLASSINFO_MAP_BEGIN(XPathNSResolver
, nsIDOMXPathNSResolver
)
881 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNSResolver
)
882 DOM_CLASSINFO_MAP_END
884 DOM_CLASSINFO_MAP_BEGIN(Blob
, nsIDOMBlob
)
885 DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob
)
886 DOM_CLASSINFO_MAP_END
888 DOM_CLASSINFO_MAP_BEGIN(File
, nsIDOMFile
)
889 DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob
)
890 DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile
)
891 DOM_CLASSINFO_MAP_END
893 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow
, nsIDOMWindow
)
894 DOM_CLASSINFO_WINDOW_MAP_ENTRIES
895 DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow
)
897 DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter
)
899 DOM_CLASSINFO_MAP_END
901 DOM_CLASSINFO_MAP_BEGIN(MozSmsMessage
, nsIDOMMozSmsMessage
)
902 DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsMessage
)
903 DOM_CLASSINFO_MAP_END
905 DOM_CLASSINFO_MAP_BEGIN(MozMmsMessage
, nsIDOMMozMmsMessage
)
906 DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMmsMessage
)
907 DOM_CLASSINFO_MAP_END
909 DOM_CLASSINFO_MAP_BEGIN(MozMobileMessageThread
, nsIDOMMozMobileMessageThread
)
910 DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMobileMessageThread
)
911 DOM_CLASSINFO_MAP_END
913 DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule
, nsIDOMCSSFontFaceRule
)
914 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule
)
915 DOM_CLASSINFO_MAP_END
917 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ContentFrameMessageManager
, nsISupports
)
918 DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget
)
919 DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager
)
920 DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender
)
921 DOM_CLASSINFO_MAP_ENTRY(nsISyncMessageSender
)
922 DOM_CLASSINFO_MAP_ENTRY(nsIContentFrameMessageManager
)
923 DOM_CLASSINFO_MAP_END
925 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageBroadcaster
, nsISupports
)
926 DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader
)
927 DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager
)
928 DOM_CLASSINFO_MAP_ENTRY(nsIMessageBroadcaster
)
929 DOM_CLASSINFO_MAP_END
931 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageSender
, nsISupports
)
932 DOM_CLASSINFO_MAP_ENTRY(nsIProcessChecker
)
933 DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader
)
934 DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager
)
935 DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender
)
936 DOM_CLASSINFO_MAP_END
938 DOM_CLASSINFO_MAP_BEGIN(MozCSSKeyframeRule
, nsIDOMMozCSSKeyframeRule
)
939 DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframeRule
)
940 DOM_CLASSINFO_MAP_END
942 DOM_CLASSINFO_MAP_BEGIN(MozCSSKeyframesRule
, nsIDOMMozCSSKeyframesRule
)
943 DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframesRule
)
944 DOM_CLASSINFO_MAP_END
946 DOM_CLASSINFO_MAP_BEGIN(CSSCounterStyleRule
, nsIDOMCSSCounterStyleRule
)
947 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSCounterStyleRule
)
948 DOM_CLASSINFO_MAP_END
950 DOM_CLASSINFO_MAP_BEGIN(CSSPageRule
, nsIDOMCSSPageRule
)
951 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSPageRule
)
952 DOM_CLASSINFO_MAP_END
954 DOM_CLASSINFO_MAP_BEGIN(CSSFontFeatureValuesRule
, nsIDOMCSSFontFeatureValuesRule
)
955 DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule
)
956 DOM_CLASSINFO_MAP_END
958 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(UserDataHandler
, nsIDOMUserDataHandler
)
959 DOM_CLASSINFO_MAP_ENTRY(nsIDOMUserDataHandler
)
960 DOM_CLASSINFO_MAP_END
962 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControlElement
, nsIDOMXULControlElement
)
963 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULControlElement
)
964 DOM_CLASSINFO_MAP_END
966 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULLabeledControlElement
, nsIDOMXULLabeledControlElement
)
967 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULLabeledControlElement
)
968 DOM_CLASSINFO_MAP_END
970 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULButtonElement
, nsIDOMXULButtonElement
)
971 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULButtonElement
)
972 DOM_CLASSINFO_MAP_END
974 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULCheckboxElement
, nsIDOMXULCheckboxElement
)
975 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULCheckboxElement
)
976 DOM_CLASSINFO_MAP_END
978 DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULPopupElement
, nsIDOMXULPopupElement
)
979 DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULPopupElement
)
980 DOM_CLASSINFO_MAP_END
982 static_assert(MOZ_ARRAY_LENGTH(sClassInfoData
) == eDOMClassInfoIDCount
,
983 "The number of items in sClassInfoData doesn't match the "
984 "number of nsIDOMClassInfo ID's, this is bad! Fix it!");
987 for (size_t i
= 0; i
< eDOMClassInfoIDCount
; i
++) {
988 if (!sClassInfoData
[i
].u
.mConstructorFptr
||
989 sClassInfoData
[i
].mDebugID
!= i
) {
990 MOZ_CRASH("Class info data out of sync, you forgot to update "
991 "nsDOMClassInfo.h and nsDOMClassInfo.cpp! Fix this, "
992 "mozilla will not work without this fixed!");
996 for (size_t i
= 0; i
< eDOMClassInfoIDCount
; i
++) {
997 if (!sClassInfoData
[i
].mInterfaces
) {
998 MOZ_CRASH("Class info data without an interface list! Fix this, "
999 "mozilla will not work without this fixed!");
1004 // Initialize static JSString's
1005 DefineStaticJSVals(cx
);
1009 for (i
= 0; i
< eDOMClassInfoIDCount
; ++i
) {
1010 if (i
== eDOMClassInfo_DOMPrototype_id
) {
1014 nsDOMClassInfoData
& data
= sClassInfoData
[i
];
1015 nameSpaceManager
->RegisterClassName(data
.mName
, i
, data
.mChromeOnly
,
1016 data
.mAllowXBL
, &data
.mNameUTF16
);
1019 for (i
= 0; i
< eDOMClassInfoIDCount
; ++i
) {
1020 RegisterClassProtos(i
);
1023 RegisterExternalClasses();
1025 sIsInitialized
= true;
1031 nsDOMClassInfo::GetInterfaces(uint32_t *aCount
, nsIID
***aArray
)
1035 while (mData
->mInterfaces
[count
]) {
1047 *aArray
= static_cast<nsIID
**>(nsMemory::Alloc(count
* sizeof(nsIID
*)));
1048 NS_ENSURE_TRUE(*aArray
, NS_ERROR_OUT_OF_MEMORY
);
1051 for (i
= 0; i
< count
; i
++) {
1052 nsIID
*iid
= static_cast<nsIID
*>(nsMemory::Clone(mData
->mInterfaces
[i
],
1056 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i
, *aArray
);
1058 return NS_ERROR_OUT_OF_MEMORY
;
1061 *((*aArray
) + i
) = iid
;
1068 nsDOMClassInfo::GetHelperForLanguage(uint32_t language
, nsISupports
**_retval
)
1070 if (language
== nsIProgrammingLanguage::JAVASCRIPT
) {
1071 *_retval
= static_cast<nsIXPCScriptable
*>(this);
1073 NS_ADDREF(*_retval
);
1082 nsDOMClassInfo::GetContractID(char **aContractID
)
1084 *aContractID
= nullptr;
1090 nsDOMClassInfo::GetClassDescription(char **aClassDescription
)
1092 return GetClassName(aClassDescription
);
1096 nsDOMClassInfo::GetClassID(nsCID
**aClassID
)
1098 *aClassID
= nullptr;
1103 nsDOMClassInfo::GetClassIDNoAlloc(nsCID
*aClassID
)
1105 return NS_ERROR_NOT_AVAILABLE
;
1109 nsDOMClassInfo::GetImplementationLanguage(uint32_t *aImplLanguage
)
1111 *aImplLanguage
= nsIProgrammingLanguage::CPLUSPLUS
;
1117 nsDOMClassInfo::GetFlags(uint32_t *aFlags
)
1119 *aFlags
= DOMCLASSINFO_STANDARD_FLAGS
;
1127 nsDOMClassInfo::GetClassName(char **aClassName
)
1129 *aClassName
= NS_strdup(mData
->mName
);
1136 nsDOMClassInfo::GetScriptableFlags()
1138 return mData
->mScriptableFlags
;
1142 nsDOMClassInfo::PreCreate(nsISupports
*nativeObj
, JSContext
*cx
,
1143 JSObject
*globalObj
, JSObject
**parentObj
)
1145 *parentObj
= globalObj
;
1150 nsDOMClassInfo::Create(nsIXPConnectWrappedNative
*wrapper
,
1151 JSContext
*cx
, JSObject
*obj
)
1153 NS_WARNING("nsDOMClassInfo::Create Don't call me!");
1155 return NS_ERROR_UNEXPECTED
;
1159 nsDOMClassInfo::PostCreate(nsIXPConnectWrappedNative
*wrapper
,
1160 JSContext
*cx
, JSObject
*obj
)
1162 NS_WARNING("nsDOMClassInfo::PostCreate Don't call me!");
1164 return NS_ERROR_UNEXPECTED
;
1168 nsDOMClassInfo::PostTransplant(nsIXPConnectWrappedNative
*wrapper
,
1169 JSContext
*cx
, JSObject
*obj
)
1171 MOZ_CRASH("nsDOMClassInfo::PostTransplant Don't call me!");
1175 nsDOMClassInfo::AddProperty(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1176 JSObject
*obj
, jsid id
, jsval
*vp
,
1179 NS_WARNING("nsDOMClassInfo::AddProperty Don't call me!");
1181 return NS_ERROR_UNEXPECTED
;
1185 nsDOMClassInfo::DelProperty(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1186 JSObject
*obj
, jsid id
, bool *_retval
)
1188 NS_WARNING("nsDOMClassInfo::DelProperty Don't call me!");
1190 return NS_ERROR_UNEXPECTED
;
1194 nsDOMClassInfo::GetProperty(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1195 JSObject
*obj
, jsid id
, jsval
*vp
,
1198 NS_WARNING("nsDOMClassInfo::GetProperty Don't call me!");
1204 nsDOMClassInfo::SetProperty(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1205 JSObject
*obj
, jsid id
, jsval
*vp
,
1208 NS_WARNING("nsDOMClassInfo::SetProperty Don't call me!");
1210 return NS_ERROR_UNEXPECTED
;
1214 nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1215 JSObject
*obj
, bool *_retval
)
1221 nsDOMClassInfo::NewEnumerate(nsIXPConnectWrappedNative
*wrapper
,
1222 JSContext
*cx
, JSObject
*obj
, uint32_t enum_op
,
1223 jsval
*statep
, jsid
*idp
, bool *_retval
)
1225 NS_WARNING("nsDOMClassInfo::NewEnumerate Don't call me!");
1227 return NS_ERROR_UNEXPECTED
;
1231 nsDOMClassInfo::ResolveConstructor(JSContext
*cx
, JSObject
*aObj
,
1234 JS::Rooted
<JSObject
*> obj(cx
, aObj
);
1235 JS::Rooted
<JSObject
*> global(cx
, ::JS_GetGlobalForObject(cx
, obj
));
1237 JS::Rooted
<JS::Value
> val(cx
);
1238 if (!::JS_LookupProperty(cx
, global
, mData
->mName
, &val
)) {
1239 return NS_ERROR_UNEXPECTED
;
1242 if (!val
.isPrimitive()) {
1243 // If val is not an (non-null) object there either is no
1244 // constructor for this class, or someone messed with
1245 // window.classname, just fall through and let the JS engine
1246 // return the Object constructor.
1248 JS::Rooted
<jsid
> id(cx
, sConstructor_id
);
1249 if (!::JS_DefinePropertyById(cx
, obj
, id
, val
, JSPROP_ENUMERATE
,
1250 JS_PropertyStub
, JS_StrictPropertyStub
)) {
1251 return NS_ERROR_UNEXPECTED
;
1261 nsDOMClassInfo::NewResolve(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1262 JSObject
*obj
, jsid id
, JSObject
**objp
,
1265 if (id
== sConstructor_id
) {
1266 return ResolveConstructor(cx
, obj
, objp
);
1273 nsDOMClassInfo::Convert(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1274 JSObject
*obj
, uint32_t type
, jsval
*vp
,
1277 NS_WARNING("nsDOMClassInfo::Convert Don't call me!");
1279 return NS_ERROR_UNEXPECTED
;
1283 nsDOMClassInfo::Finalize(nsIXPConnectWrappedNative
*wrapper
, JSFreeOp
*fop
,
1286 NS_WARNING("nsDOMClassInfo::Finalize Don't call me!");
1288 return NS_ERROR_UNEXPECTED
;
1292 nsDOMClassInfo::Call(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1293 JSObject
*obj
, const JS::CallArgs
&args
, bool *_retval
)
1295 NS_WARNING("nsDOMClassInfo::Call Don't call me!");
1297 return NS_ERROR_UNEXPECTED
;
1301 nsDOMClassInfo::Construct(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1302 JSObject
*obj
, const JS::CallArgs
&args
,
1305 NS_WARNING("nsDOMClassInfo::Construct Don't call me!");
1307 return NS_ERROR_UNEXPECTED
;
1311 nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1312 JSObject
*obj
, JS::Handle
<JS::Value
> val
, bool *bp
,
1315 NS_WARNING("nsDOMClassInfo::HasInstance Don't call me!");
1317 return NS_ERROR_UNEXPECTED
;
1321 nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative
*wrapper
, JSContext
* cx
,
1322 JSObject
* obj
, JSObject
* *_retval
)
1324 NS_WARNING("nsDOMClassInfo::OuterObject Don't call me!");
1326 return NS_ERROR_UNEXPECTED
;
1330 GetExternalClassInfo(nsScriptNameSpaceManager
*aNameSpaceManager
,
1331 const nsAString
&aName
,
1332 const nsGlobalNameStruct
*aStruct
,
1333 const nsGlobalNameStruct
**aResult
)
1335 NS_ASSERTION(aStruct
->mType
==
1336 nsGlobalNameStruct::eTypeExternalClassInfoCreator
,
1340 nsCOMPtr
<nsIDOMCIExtension
> creator(do_CreateInstance(aStruct
->mCID
, &rv
));
1341 NS_ENSURE_SUCCESS(rv
, rv
);
1343 nsCOMPtr
<nsIDOMScriptObjectFactory
> sof(do_GetService(kDOMSOF_CID
));
1344 NS_ENSURE_TRUE(sof
, NS_ERROR_FAILURE
);
1346 rv
= creator
->RegisterDOMCI(NS_ConvertUTF16toUTF8(aName
).get(), sof
);
1347 NS_ENSURE_SUCCESS(rv
, rv
);
1349 const nsGlobalNameStruct
*name_struct
= aNameSpaceManager
->LookupName(aName
);
1351 name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
1352 *aResult
= name_struct
;
1355 NS_ERROR("Couldn't get the DOM ClassInfo data.");
1365 ResolvePrototype(nsIXPConnect
*aXPConnect
, nsGlobalWindow
*aWin
, JSContext
*cx
,
1366 JS::Handle
<JSObject
*> obj
, const char16_t
*name
,
1367 const nsDOMClassInfoData
*ci_data
,
1368 const nsGlobalNameStruct
*name_struct
,
1369 nsScriptNameSpaceManager
*nameSpaceManager
,
1370 JSObject
*dot_prototype
,
1371 JS::MutableHandle
<JSPropertyDescriptor
> ctorDesc
);
1374 nsDOMClassInfo::PostCreatePrototype(JSContext
* cx
, JSObject
* aProto
)
1376 uint32_t flags
= (mData
->mScriptableFlags
& DONT_ENUM_STATIC_PROPS
)
1381 while (mData
->mInterfaces
[count
]) {
1385 JS::Rooted
<JSObject
*> proto(cx
, aProto
);
1386 if (!xpc::DOM_DefineQuickStubs(cx
, proto
, flags
, count
, mData
->mInterfaces
)) {
1387 JS_ClearPendingException(cx
);
1390 // This is called before any other location that requires
1391 // sObjectClass, so compute it here. We assume that nobody has had a
1392 // chance to monkey around with proto's prototype chain before this.
1393 if (!sObjectClass
) {
1394 FindObjectClass(cx
, proto
);
1395 NS_ASSERTION(sObjectClass
&& !strcmp(sObjectClass
->name
, "Object"),
1396 "Incorrect object class!");
1400 JS::Rooted
<JSObject
*> proto2(cx
);
1401 JS_GetPrototype(cx
, proto
, &proto2
);
1402 NS_ASSERTION(proto2
&& JS_GetClass(proto2
) == sObjectClass
,
1403 "Hmm, somebody did something evil?");
1407 if (mData
->mHasClassInterface
&& mData
->mProtoChainInterface
&&
1408 mData
->mProtoChainInterface
!= &NS_GET_IID(nsISupports
)) {
1409 nsCOMPtr
<nsIInterfaceInfoManager
>
1410 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
1413 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
1414 iim
->GetInfoForIID(mData
->mProtoChainInterface
,
1415 getter_AddRefs(if_info
));
1418 nsXPIDLCString name
;
1419 if_info
->GetName(getter_Copies(name
));
1420 NS_ASSERTION(nsCRT::strcmp(CutPrefix(name
), mData
->mName
) == 0,
1421 "Class name and proto chain interface name mismatch!");
1427 // Make prototype delegation work correctly. Consider if a site sets
1428 // HTMLElement.prototype.foopy = function () { ... } Now, calling
1429 // document.body.foopy() needs to ensure that looking up foopy on
1430 // document.body's prototype will find the right function.
1431 JS::Rooted
<JSObject
*> global(cx
, ::JS_GetGlobalForObject(cx
, proto
));
1433 // Only do this if the global object is a window.
1434 // XXX Is there a better way to check this?
1435 nsISupports
*globalNative
= XPConnect()->GetNativeOfWrapper(cx
, global
);
1436 nsCOMPtr
<nsPIDOMWindow
> piwin
= do_QueryInterface(globalNative
);
1441 nsGlobalWindow
*win
= nsGlobalWindow::FromSupports(globalNative
);
1442 if (win
->IsClosedOrClosing()) {
1446 // If the window is in a different compartment than the global object, then
1447 // it's likely that global is a sandbox object whose prototype is a window.
1448 // Don't do anything in this case.
1449 if (win
->FastGetGlobalJSObject() &&
1450 js::GetObjectCompartment(global
) != js::GetObjectCompartment(win
->FastGetGlobalJSObject())) {
1454 if (win
->IsOuterWindow()) {
1455 // XXXjst: Do security checks here when we remove the security
1456 // checks on the inner window.
1458 win
= win
->GetCurrentInnerWindowInternal();
1460 if (!win
|| !(global
= win
->GetGlobalJSObject()) ||
1461 win
->IsClosedOrClosing()) {
1466 // Don't overwrite a property set by content.
1467 bool contentDefinedProperty
;
1468 if (!::JS_AlreadyHasOwnUCProperty(cx
, global
, reinterpret_cast<const jschar
*>(mData
->mNameUTF16
),
1469 NS_strlen(mData
->mNameUTF16
),
1470 &contentDefinedProperty
)) {
1471 return NS_ERROR_FAILURE
;
1474 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
1475 NS_ENSURE_TRUE(nameSpaceManager
, NS_OK
);
1477 JS::Rooted
<JSPropertyDescriptor
> desc(cx
);
1478 nsresult rv
= ResolvePrototype(sXPConnect
, win
, cx
, global
, mData
->mNameUTF16
,
1479 mData
, nullptr, nameSpaceManager
, proto
,
1481 NS_ENSURE_SUCCESS(rv
, rv
);
1482 if (!contentDefinedProperty
&& desc
.object() && !desc
.value().isUndefined() &&
1483 !JS_DefineUCProperty(cx
, global
, mData
->mNameUTF16
,
1484 NS_strlen(mData
->mNameUTF16
),
1485 desc
.value(), desc
.attributes(),
1486 desc
.getter(), desc
.setter())) {
1487 return NS_ERROR_UNEXPECTED
;
1495 NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID
)
1497 if (aID
>= eDOMClassInfoIDCount
) {
1498 NS_ERROR("Bad ID!");
1503 nsresult rv
= RegisterDOMNames();
1504 NS_ENSURE_SUCCESS(rv
, nullptr);
1506 if (!sClassInfoData
[aID
].mCachedClassInfo
) {
1507 nsDOMClassInfoData
& data
= sClassInfoData
[aID
];
1509 data
.mCachedClassInfo
= data
.u
.mConstructorFptr(&data
);
1510 NS_ENSURE_TRUE(data
.mCachedClassInfo
, nullptr);
1512 NS_ADDREF(data
.mCachedClassInfo
);
1515 NS_ASSERTION(!IS_EXTERNAL(sClassInfoData
[aID
].mCachedClassInfo
),
1516 "This is bad, internal class marked as external!");
1518 return sClassInfoData
[aID
].mCachedClassInfo
;
1523 nsDOMClassInfo::GetClassInfoInstance(nsDOMClassInfoData
* aData
)
1525 NS_ASSERTION(IS_EXTERNAL(aData
->mCachedClassInfo
)
1526 || !aData
->mCachedClassInfo
,
1527 "This is bad, external class marked as internal!");
1529 if (!aData
->mCachedClassInfo
) {
1530 if (aData
->u
.mExternalConstructorFptr
) {
1531 aData
->mCachedClassInfo
=
1532 aData
->u
.mExternalConstructorFptr(aData
->mName
);
1534 aData
->mCachedClassInfo
= nsDOMGenericSH::doCreate(aData
);
1536 NS_ENSURE_TRUE(aData
->mCachedClassInfo
, nullptr);
1538 NS_ADDREF(aData
->mCachedClassInfo
);
1539 aData
->mCachedClassInfo
= MARK_EXTERNAL(aData
->mCachedClassInfo
);
1542 return GET_CLEAN_CI_PTR(aData
->mCachedClassInfo
);
1548 nsDOMClassInfo::ShutDown()
1550 if (sClassInfoData
[0].u
.mConstructorFptr
) {
1553 for (i
= 0; i
< eDOMClassInfoIDCount
; i
++) {
1554 NS_IF_RELEASE(sClassInfoData
[i
].mCachedClassInfo
);
1558 sLocation_id
= JSID_VOID
;
1559 sConstructor_id
= JSID_VOID
;
1560 sTop_id
= JSID_VOID
;
1561 sDocument_id
= JSID_VOID
;
1562 sWrappedJSObject_id
= JSID_VOID
;
1564 NS_IF_RELEASE(sXPConnect
);
1565 sIsInitialized
= false;
1571 nsWindowSH::PreCreate(nsISupports
*nativeObj
, JSContext
*cx
,
1572 JSObject
*globalObj
, JSObject
**parentObj
)
1574 // Normally ::PreCreate() is used to give XPConnect the parent
1575 // object for the object that's being wrapped, this parent object is
1576 // set as the parent of the wrapper and it's also used to find the
1577 // right scope for the object being wrapped. Now, in the case of the
1578 // global object the wrapper shouldn't have a parent but we supply
1579 // one here anyway (the global object itself) and this will be used
1580 // by XPConnect only to find the right scope, once the scope is
1581 // found XPConnect will find the existing wrapper (which always
1582 // exists since it's created on window construction), since an
1583 // existing wrapper is found the parent we supply here is ignored
1584 // after the wrapper is found.
1586 nsCOMPtr
<nsIScriptGlobalObject
> sgo(do_QueryInterface(nativeObj
));
1587 NS_ASSERTION(sgo
, "nativeObj not a global object!");
1589 nsGlobalWindow
*win
= nsGlobalWindow::FromSupports(nativeObj
);
1590 NS_ASSERTION(win
->IsInnerWindow(), "Should be inner window.");
1592 // We sometimes get a disconnected window during file api test. :-(
1593 if (!win
->GetOuterWindowInternal())
1594 return NS_ERROR_FAILURE
;
1596 // If we're bootstrapping, we don't have a JS object yet.
1597 if (win
->GetOuterWindowInternal()->IsCreatingInnerWindow())
1600 return SetParentToWindow(win
, parentObj
);
1604 nsWindowSH::PostCreatePrototype(JSContext
* aCx
, JSObject
* aProto
)
1606 JS::Rooted
<JSObject
*> proto(aCx
, aProto
);
1608 nsresult rv
= nsDOMClassInfo::PostCreatePrototype(aCx
, proto
);
1609 NS_ENSURE_SUCCESS(rv
, rv
);
1611 // We should probably move this into the CreateInterfaceObjects for Window
1612 // once it is on WebIDL bindings.
1613 WindowNamedPropertiesHandler::Install(aCx
, proto
);
1618 nsWindowSH::PostCreate(nsIXPConnectWrappedNative
*wrapper
,
1619 JSContext
*cx
, JSObject
*obj
)
1621 JS::Rooted
<JSObject
*> window(cx
, obj
);
1624 nsCOMPtr
<nsIScriptGlobalObject
> sgo(do_QueryWrappedNative(wrapper
));
1626 NS_ASSERTION(sgo
&& sgo
->GetGlobalJSObject() == obj
,
1627 "Multiple wrappers created for global object!");
1630 const NativeProperties
* windowProperties
=
1631 WindowBinding::sNativePropertyHooks
->mNativeProperties
.regular
;
1632 const NativeProperties
* eventTargetProperties
=
1633 EventTargetBinding::sNativePropertyHooks
->mNativeProperties
.regular
;
1635 if (!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx
, window
, windowProperties
) ||
1636 !DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx
, window
, eventTargetProperties
)) {
1637 return NS_ERROR_FAILURE
;
1640 if (!GlobalPropertiesAreOwn()) {
1644 return DefineWebIDLBindingPropertiesOnXPCObject(cx
, window
, windowProperties
) &&
1645 DefineWebIDLBindingPropertiesOnXPCObject(cx
, window
, eventTargetProperties
) ?
1646 NS_OK
: NS_ERROR_FAILURE
;
1649 struct ResolveGlobalNameClosure
1652 JS::Handle
<JSObject
*> obj
;
1656 static PLDHashOperator
1657 ResolveGlobalName(const nsAString
& aName
,
1658 const nsGlobalNameStruct
& aNameStruct
,
1661 ResolveGlobalNameClosure
* closure
=
1662 static_cast<ResolveGlobalNameClosure
*>(aClosure
);
1663 JS::Rooted
<JS::Value
> dummy(closure
->cx
);
1664 bool ok
= JS_LookupUCProperty(closure
->cx
, closure
->obj
,
1665 aName
.BeginReading(), aName
.Length(),
1668 *closure
->retval
= false;
1669 return PL_DHASH_STOP
;
1671 return PL_DHASH_NEXT
;
1675 nsWindowSH::Enumerate(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1676 JSObject
*aObj
, bool *_retval
)
1678 JS::Rooted
<JSObject
*> obj(cx
, aObj
);
1679 if (!xpc::WrapperFactory::IsXrayWrapper(obj
)) {
1680 *_retval
= JS_EnumerateStandardClasses(cx
, obj
);
1685 // Now resolve everything from the namespace manager
1686 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
1687 if (!nameSpaceManager
) {
1688 NS_ERROR("Can't get namespace manager.");
1689 return NS_ERROR_UNEXPECTED
;
1691 ResolveGlobalNameClosure closure
= { cx
, obj
, _retval
};
1692 nameSpaceManager
->EnumerateGlobalNames(ResolveGlobalName
, &closure
);
1698 static nsDOMConstructorFunc
1699 FindConstructorFunc(const nsDOMClassInfoData
*aDOMClassInfoData
)
1701 for (uint32_t i
= 0; i
< ArrayLength(kConstructorFuncMap
); ++i
) {
1702 if (&sClassInfoData
[kConstructorFuncMap
[i
].mDOMClassInfoID
] ==
1703 aDOMClassInfoData
) {
1704 return kConstructorFuncMap
[i
].mConstructorFunc
;
1711 BaseStubConstructor(nsIWeakReference
* aWeakOwner
,
1712 const nsGlobalNameStruct
*name_struct
, JSContext
*cx
,
1713 JS::Handle
<JSObject
*> obj
, const JS::CallArgs
&args
)
1716 MOZ_ASSERT(cx
== nsContentUtils::GetCurrentJSContext());
1719 nsCOMPtr
<nsISupports
> native
;
1720 if (name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
1721 const nsDOMClassInfoData
* ci_data
=
1722 &sClassInfoData
[name_struct
->mDOMClassInfoID
];
1723 nsDOMConstructorFunc func
= FindConstructorFunc(ci_data
);
1725 rv
= func(getter_AddRefs(native
));
1727 rv
= NS_ERROR_NOT_AVAILABLE
;
1729 } else if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
) {
1730 native
= do_CreateInstance(name_struct
->mCID
, &rv
);
1731 } else if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
1732 native
= do_CreateInstance(name_struct
->mAlias
->mCID
, &rv
);
1734 native
= do_CreateInstance(*name_struct
->mData
->mConstructorCID
, &rv
);
1736 if (NS_FAILED(rv
)) {
1737 NS_ERROR("Failed to create the object");
1741 nsCOMPtr
<nsIJSNativeInitializer
> initializer(do_QueryInterface(native
));
1742 nsCOMPtr
<nsIDOMGlobalObjectConstructor
> constructor(do_QueryInterface(native
));
1743 if (initializer
|| constructor
) {
1744 // Initialize object using the current inner window, but only if
1745 // the caller can access it.
1746 nsCOMPtr
<nsPIDOMWindow
> owner
= do_QueryReferent(aWeakOwner
);
1747 nsPIDOMWindow
* outerWindow
= owner
? owner
->GetOuterWindow() : nullptr;
1748 nsPIDOMWindow
* currentInner
=
1749 outerWindow
? outerWindow
->GetCurrentInnerWindow() : nullptr;
1750 if (!currentInner
||
1751 (owner
!= currentInner
&&
1752 !nsContentUtils::CanCallerAccess(currentInner
))) {
1753 return NS_ERROR_DOM_SECURITY_ERR
;
1757 rv
= initializer
->Initialize(currentInner
, cx
, obj
, args
);
1758 if (NS_FAILED(rv
)) {
1762 nsCOMPtr
<nsIXPConnectWrappedJS
> wrappedJS
= do_QueryInterface(native
);
1764 JS::Rooted
<JSObject
*> thisObject(cx
, wrappedJS
->GetJSObject());
1766 return NS_ERROR_UNEXPECTED
;
1769 JSAutoCompartment
ac(cx
, thisObject
);
1771 JS::Rooted
<JS::Value
> funval(cx
);
1772 if (!JS_GetProperty(cx
, thisObject
, "constructor", &funval
) ||
1773 !funval
.isObject()) {
1774 return NS_ERROR_UNEXPECTED
;
1777 // Check if the object is even callable.
1778 NS_ENSURE_STATE(JS_ObjectIsCallable(cx
, &funval
.toObject()));
1780 // wrap parameters in the target compartment
1781 // we also pass in the calling window as the first argument
1782 unsigned argc
= args
.length() + 1;
1783 JS::AutoValueVector
argv(cx
);
1784 if (!argv
.resize(argc
)) {
1785 return NS_ERROR_OUT_OF_MEMORY
;
1788 nsCOMPtr
<nsIDOMWindow
> currentWin(do_GetInterface(currentInner
));
1789 rv
= WrapNative(cx
, currentWin
, &NS_GET_IID(nsIDOMWindow
),
1792 for (size_t i
= 1; i
< argc
; ++i
) {
1793 argv
[i
].set(args
[i
- 1]);
1794 if (!JS_WrapValue(cx
, argv
[i
]))
1795 return NS_ERROR_FAILURE
;
1798 JS::Rooted
<JS::Value
> frval(cx
);
1799 bool ret
= JS_CallFunctionValue(cx
, thisObject
, funval
, argv
, &frval
);
1802 return NS_ERROR_FAILURE
;
1808 js::AssertSameCompartment(cx
, obj
);
1809 return WrapNative(cx
, native
, true, args
.rval());
1813 DefineInterfaceConstants(JSContext
*cx
, JS::Handle
<JSObject
*> obj
, const nsIID
*aIID
)
1815 nsCOMPtr
<nsIInterfaceInfoManager
>
1816 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
1817 NS_ENSURE_TRUE(iim
, NS_ERROR_UNEXPECTED
);
1819 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
1821 nsresult rv
= iim
->GetInfoForIID(aIID
, getter_AddRefs(if_info
));
1822 NS_ENSURE_TRUE(NS_SUCCEEDED(rv
) && if_info
, rv
);
1824 uint16_t constant_count
;
1826 if_info
->GetConstantCount(&constant_count
);
1828 if (!constant_count
) {
1832 nsCOMPtr
<nsIInterfaceInfo
> parent_if_info
;
1834 rv
= if_info
->GetParent(getter_AddRefs(parent_if_info
));
1835 NS_ENSURE_TRUE(NS_SUCCEEDED(rv
) && parent_if_info
, rv
);
1837 uint16_t parent_constant_count
, i
;
1838 parent_if_info
->GetConstantCount(&parent_constant_count
);
1840 JS::Rooted
<JS::Value
> v(cx
);
1841 for (i
= parent_constant_count
; i
< constant_count
; i
++) {
1842 nsXPIDLCString name
;
1843 rv
= if_info
->GetConstant(i
, &v
, getter_Copies(name
));
1844 NS_ENSURE_TRUE(NS_SUCCEEDED(rv
), rv
);
1846 if (!::JS_DefineProperty(cx
, obj
, name
, v
,
1847 JSPROP_ENUMERATE
| JSPROP_READONLY
|
1849 JS_PropertyStub
, JS_StrictPropertyStub
)) {
1850 return NS_ERROR_UNEXPECTED
;
1857 class nsDOMConstructor MOZ_FINAL
: public nsIDOMDOMConstructor
1860 nsDOMConstructor(const char16_t
* aName
,
1861 bool aIsConstructable
,
1862 nsPIDOMWindow
* aOwner
)
1863 : mClassName(aName
),
1864 mConstructable(aIsConstructable
),
1865 mWeakOwner(do_GetWeakReference(aOwner
))
1869 ~nsDOMConstructor() {}
1873 static nsresult
Create(const char16_t
* aName
,
1874 const nsDOMClassInfoData
* aData
,
1875 const nsGlobalNameStruct
* aNameStruct
,
1876 nsPIDOMWindow
* aOwner
,
1877 nsDOMConstructor
** aResult
);
1880 NS_DECL_NSIDOMDOMCONSTRUCTOR
1882 nsresult
PreCreate(JSContext
*cx
, JSObject
*globalObj
, JSObject
**parentObj
);
1884 nsresult
Construct(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1885 JS::Handle
<JSObject
*> obj
, const JS::CallArgs
&args
,
1888 nsresult
HasInstance(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
1889 JS::Handle
<JSObject
*> obj
, const jsval
&val
, bool *bp
,
1892 nsresult
ResolveInterfaceConstants(JSContext
*cx
, JS::Handle
<JSObject
*> obj
);
1895 const nsGlobalNameStruct
*GetNameStruct()
1898 NS_ERROR("Can't get name");
1902 const nsGlobalNameStruct
*nameStruct
;
1906 GetNameStruct(nsDependentString(mClassName
), &nameStruct
);
1908 NS_ASSERTION(NS_FAILED(rv
) || nameStruct
, "Name isn't in hash.");
1913 static nsresult
GetNameStruct(const nsAString
& aName
,
1914 const nsGlobalNameStruct
**aNameStruct
)
1916 *aNameStruct
= nullptr;
1918 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
1919 if (!nameSpaceManager
) {
1920 NS_ERROR("Can't get namespace manager.");
1921 return NS_ERROR_UNEXPECTED
;
1924 *aNameStruct
= nameSpaceManager
->LookupName(aName
);
1926 // Return NS_OK here, aName just isn't a DOM class but nothing failed.
1930 static bool IsConstructable(const nsDOMClassInfoData
*aData
)
1932 if (IS_EXTERNAL(aData
->mCachedClassInfo
)) {
1933 const nsExternalDOMClassInfoData
* data
=
1934 static_cast<const nsExternalDOMClassInfoData
*>(aData
);
1935 return data
->mConstructorCID
!= nullptr;
1938 return FindConstructorFunc(aData
);
1940 static bool IsConstructable(const nsGlobalNameStruct
*aNameStruct
)
1943 (aNameStruct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
&&
1944 IsConstructable(&sClassInfoData
[aNameStruct
->mDOMClassInfoID
])) ||
1945 (aNameStruct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
&&
1946 IsConstructable(aNameStruct
->mData
)) ||
1947 aNameStruct
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
||
1948 aNameStruct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
;
1951 const char16_t
* mClassName
;
1952 const bool mConstructable
;
1953 nsWeakPtr mWeakOwner
;
1958 nsDOMConstructor::Create(const char16_t
* aName
,
1959 const nsDOMClassInfoData
* aData
,
1960 const nsGlobalNameStruct
* aNameStruct
,
1961 nsPIDOMWindow
* aOwner
,
1962 nsDOMConstructor
** aResult
)
1965 // Prevent creating a constructor if aOwner is inner window which doesn't have
1966 // an outer window. If the outer window doesn't have an inner window or the
1967 // caller can't access the outer window's current inner window then try to use
1968 // the owner (so long as it is, in fact, an inner window). If that doesn't
1969 // work then prevent creation also.
1970 nsPIDOMWindow
* outerWindow
= aOwner
->GetOuterWindow();
1971 nsPIDOMWindow
* currentInner
=
1972 outerWindow
? outerWindow
->GetCurrentInnerWindow() : aOwner
;
1973 if (!currentInner
||
1974 (aOwner
!= currentInner
&&
1975 !nsContentUtils::CanCallerAccess(currentInner
) &&
1976 !(currentInner
= aOwner
)->IsInnerWindow())) {
1977 return NS_ERROR_DOM_SECURITY_ERR
;
1980 bool constructable
= aNameStruct
?
1981 IsConstructable(aNameStruct
) :
1982 IsConstructable(aData
);
1984 *aResult
= new nsDOMConstructor(aName
, constructable
, currentInner
);
1985 NS_ENSURE_TRUE(*aResult
, NS_ERROR_OUT_OF_MEMORY
);
1986 NS_ADDREF(*aResult
);
1990 NS_IMPL_ADDREF(nsDOMConstructor
)
1991 NS_IMPL_RELEASE(nsDOMConstructor
)
1992 NS_INTERFACE_MAP_BEGIN(nsDOMConstructor
)
1993 NS_INTERFACE_MAP_ENTRY(nsIDOMDOMConstructor
)
1994 NS_INTERFACE_MAP_ENTRY(nsISupports
)
1995 if (aIID
.Equals(NS_GET_IID(nsIClassInfo
))) {
1998 const nsGlobalNameStruct
*name_struct
= GetNameStruct();
1999 NS_ASSERTION(!name_struct
||
2000 mConstructable
== IsConstructable(name_struct
),
2001 "Can't change constructability dynamically!");
2005 NS_GetDOMClassInfoInstance(mConstructable
?
2006 eDOMClassInfo_DOMConstructor_id
:
2007 eDOMClassInfo_DOMPrototype_id
);
2008 if (!foundInterface
) {
2009 *aInstancePtr
= nullptr;
2010 return NS_ERROR_OUT_OF_MEMORY
;
2013 NS_INTERFACE_MAP_END
2016 nsDOMConstructor::PreCreate(JSContext
*cx
, JSObject
*globalObj
, JSObject
**parentObj
)
2018 nsCOMPtr
<nsPIDOMWindow
> owner(do_QueryReferent(mWeakOwner
));
2020 // Can't do anything.
2024 nsGlobalWindow
*win
= static_cast<nsGlobalWindow
*>(owner
.get());
2025 return SetParentToWindow(win
, parentObj
);
2029 nsDOMConstructor::Construct(nsIXPConnectWrappedNative
*wrapper
, JSContext
* cx
,
2030 JS::Handle
<JSObject
*> obj
, const JS::CallArgs
&args
,
2035 const nsGlobalNameStruct
*name_struct
= GetNameStruct();
2036 NS_ENSURE_TRUE(name_struct
, NS_ERROR_FAILURE
);
2038 if (!IsConstructable(name_struct
)) {
2039 // ignore return value, we return false anyway
2040 return NS_ERROR_DOM_NOT_SUPPORTED_ERR
;
2043 return BaseStubConstructor(mWeakOwner
, name_struct
, cx
, obj
, args
);
2047 nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative
*wrapper
,
2048 JSContext
* cx
, JS::Handle
<JSObject
*> obj
,
2049 const jsval
&v
, bool *bp
, bool *_retval
)
2052 // No need to look these up in the hash.
2054 if (v
.isPrimitive()) {
2058 JS::Rooted
<JSObject
*> dom_obj(cx
, v
.toObjectOrNull());
2059 NS_ASSERTION(dom_obj
, "nsDOMConstructor::HasInstance couldn't get object");
2061 // This might not be the right object, if there are wrappers. Unwrap if we can.
2062 JSObject
*wrapped_obj
= js::CheckedUnwrap(dom_obj
, /* stopAtOuter = */ false);
2064 dom_obj
= wrapped_obj
;
2066 const JSClass
*dom_class
= JS_GetClass(dom_obj
);
2068 NS_ERROR("nsDOMConstructor::HasInstance can't get class.");
2069 return NS_ERROR_UNEXPECTED
;
2072 const nsGlobalNameStruct
*name_struct
;
2073 nsresult rv
= GetNameStruct(NS_ConvertASCIItoUTF16(dom_class
->name
), &name_struct
);
2074 if (NS_FAILED(rv
)) {
2079 // This isn't a normal DOM object, see if this constructor lives on its
2081 JS::Rooted
<JS::Value
> val(cx
);
2082 if (!JS_GetProperty(cx
, obj
, "prototype", &val
)) {
2083 return NS_ERROR_UNEXPECTED
;
2086 if (val
.isPrimitive()) {
2090 JS::Rooted
<JSObject
*> dot_prototype(cx
, val
.toObjectOrNull());
2092 JS::Rooted
<JSObject
*> proto(cx
, dom_obj
);
2094 if (!JS_GetPrototype(cx
, proto
, &proto
)) {
2095 return NS_ERROR_UNEXPECTED
;
2100 if (proto
== dot_prototype
) {
2109 if (name_struct
->mType
!= nsGlobalNameStruct::eTypeClassConstructor
&&
2110 name_struct
->mType
!= nsGlobalNameStruct::eTypeExternalClassInfo
&&
2111 name_struct
->mType
!= nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
2112 // Doesn't have DOM interfaces.
2116 const nsGlobalNameStruct
*class_name_struct
= GetNameStruct();
2117 NS_ENSURE_TRUE(class_name_struct
, NS_ERROR_FAILURE
);
2119 if (name_struct
== class_name_struct
) {
2125 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
2126 NS_ASSERTION(nameSpaceManager
, "Can't get namespace manager?");
2128 const nsIID
*class_iid
;
2129 if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeInterface
||
2130 class_name_struct
->mType
== nsGlobalNameStruct::eTypeClassProto
) {
2131 class_iid
= &class_name_struct
->mIID
;
2132 } else if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2134 sClassInfoData
[class_name_struct
->mDOMClassInfoID
].mProtoChainInterface
;
2135 } else if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
2136 class_iid
= class_name_struct
->mData
->mProtoChainInterface
;
2137 } else if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
2138 const nsGlobalNameStruct
* alias_struct
=
2139 nameSpaceManager
->GetConstructorProto(class_name_struct
);
2140 if (!alias_struct
) {
2141 NS_ERROR("Couldn't get constructor prototype.");
2142 return NS_ERROR_UNEXPECTED
;
2145 if (alias_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2147 sClassInfoData
[alias_struct
->mDOMClassInfoID
].mProtoChainInterface
;
2148 } else if (alias_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
2149 class_iid
= alias_struct
->mData
->mProtoChainInterface
;
2151 NS_ERROR("Expected eTypeClassConstructor or eTypeExternalClassInfo.");
2152 return NS_ERROR_UNEXPECTED
;
2160 if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
2161 name_struct
= nameSpaceManager
->GetConstructorProto(name_struct
);
2163 NS_ERROR("Couldn't get constructor prototype.");
2164 return NS_ERROR_UNEXPECTED
;
2168 NS_ASSERTION(name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
||
2169 name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
,
2170 "The constructor was set up with a struct of the wrong type.");
2172 const nsDOMClassInfoData
*ci_data
= nullptr;
2173 if (name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
&&
2174 name_struct
->mDOMClassInfoID
>= 0) {
2175 ci_data
= &sClassInfoData
[name_struct
->mDOMClassInfoID
];
2176 } else if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
2177 ci_data
= name_struct
->mData
;
2180 nsCOMPtr
<nsIInterfaceInfoManager
>
2181 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
2183 NS_ERROR("nsDOMConstructor::HasInstance can't get interface info mgr.");
2184 return NS_ERROR_UNEXPECTED
;
2187 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
2189 const nsIID
* class_interface
;
2190 while ((class_interface
= ci_data
->mInterfaces
[count
++])) {
2191 if (class_iid
->Equals(*class_interface
)) {
2197 iim
->GetInfoForIID(class_interface
, getter_AddRefs(if_info
));
2199 NS_ERROR("nsDOMConstructor::HasInstance can't get interface info.");
2200 return NS_ERROR_UNEXPECTED
;
2203 if_info
->HasAncestor(class_iid
, bp
);
2214 nsDOMConstructor::ResolveInterfaceConstants(JSContext
*cx
, JS::Handle
<JSObject
*> obj
)
2216 const nsGlobalNameStruct
*class_name_struct
= GetNameStruct();
2217 if (!class_name_struct
)
2218 return NS_ERROR_UNEXPECTED
;
2220 const nsIID
*class_iid
;
2221 if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeInterface
||
2222 class_name_struct
->mType
== nsGlobalNameStruct::eTypeClassProto
) {
2223 class_iid
= &class_name_struct
->mIID
;
2224 } else if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2226 sClassInfoData
[class_name_struct
->mDOMClassInfoID
].mProtoChainInterface
;
2227 } else if (class_name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
2228 class_iid
= class_name_struct
->mData
->mProtoChainInterface
;
2233 nsresult rv
= DefineInterfaceConstants(cx
, obj
, class_iid
);
2234 NS_ENSURE_SUCCESS(rv
, rv
);
2240 nsDOMConstructor::ToString(nsAString
&aResult
)
2242 aResult
.AssignLiteral("[object ");
2243 aResult
.Append(mClassName
);
2244 aResult
.Append(char16_t(']'));
2251 GetXPCProto(nsIXPConnect
*aXPConnect
, JSContext
*cx
, nsGlobalWindow
*aWin
,
2252 const nsGlobalNameStruct
*aNameStruct
,
2253 nsIXPConnectJSObjectHolder
**aProto
)
2255 NS_ASSERTION(aNameStruct
->mType
==
2256 nsGlobalNameStruct::eTypeClassConstructor
||
2257 aNameStruct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
,
2260 nsCOMPtr
<nsIClassInfo
> ci
;
2261 if (aNameStruct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2262 int32_t id
= aNameStruct
->mDOMClassInfoID
;
2263 NS_ABORT_IF_FALSE(id
>= 0, "Negative DOM classinfo?!?");
2265 nsDOMClassInfoID ci_id
= (nsDOMClassInfoID
)id
;
2267 ci
= NS_GetDOMClassInfoInstance(ci_id
);
2269 // In most cases we want to find the wrapped native prototype in
2270 // aWin's scope and use that prototype for
2271 // ClassName.prototype. But in the case where we're setting up
2272 // "Window.prototype" or "ChromeWindow.prototype" we want to do
2273 // the look up in aWin's outer window's scope since the inner
2274 // window's wrapped native prototype comes from the outer
2276 if (ci_id
== eDOMClassInfo_Window_id
||
2277 ci_id
== eDOMClassInfo_ModalContentWindow_id
||
2278 ci_id
== eDOMClassInfo_ChromeWindow_id
) {
2279 nsGlobalWindow
*scopeWindow
= aWin
->GetOuterWindowInternal();
2287 ci
= nsDOMClassInfo::GetClassInfoInstance(aNameStruct
->mData
);
2289 NS_ENSURE_TRUE(ci
, NS_ERROR_UNEXPECTED
);
2292 aXPConnect
->GetWrappedNativePrototype(cx
, aWin
->GetGlobalJSObject(), ci
,
2294 NS_ENSURE_SUCCESS(rv
, rv
);
2296 JS::Rooted
<JSObject
*> proto_obj(cx
, (*aProto
)->GetJSObject());
2297 if (!JS_WrapObject(cx
, &proto_obj
)) {
2298 return NS_ERROR_FAILURE
;
2301 NS_IF_RELEASE(*aProto
);
2302 return aXPConnect
->HoldObject(cx
, proto_obj
, aProto
);
2305 // Either ci_data must be non-null or name_struct must be non-null and of type
2308 ResolvePrototype(nsIXPConnect
*aXPConnect
, nsGlobalWindow
*aWin
, JSContext
*cx
,
2309 JS::Handle
<JSObject
*> obj
, const char16_t
*name
,
2310 const nsDOMClassInfoData
*ci_data
,
2311 const nsGlobalNameStruct
*name_struct
,
2312 nsScriptNameSpaceManager
*nameSpaceManager
,
2313 JSObject
* aDot_prototype
,
2314 JS::MutableHandle
<JSPropertyDescriptor
> ctorDesc
)
2316 JS::Rooted
<JSObject
*> dot_prototype(cx
, aDot_prototype
);
2317 NS_ASSERTION(ci_data
||
2319 name_struct
->mType
== nsGlobalNameStruct::eTypeClassProto
),
2320 "Wrong type or missing ci_data!");
2322 nsRefPtr
<nsDOMConstructor
> constructor
;
2323 nsresult rv
= nsDOMConstructor::Create(name
, ci_data
, name_struct
, aWin
,
2324 getter_AddRefs(constructor
));
2325 NS_ENSURE_SUCCESS(rv
, rv
);
2327 JS::Rooted
<JS::Value
> v(cx
);
2329 js::AssertSameCompartment(cx
, obj
);
2330 rv
= WrapNative(cx
, constructor
, &NS_GET_IID(nsIDOMDOMConstructor
),
2332 NS_ENSURE_SUCCESS(rv
, rv
);
2334 FillPropertyDescriptor(ctorDesc
, obj
, 0, v
);
2335 // And make sure we wrap the value into the right compartment. Note that we
2336 // do this with ctorDesc.value(), not with v, because we need v to be in the
2337 // right compartment (that of the reflector of |constructor|) below.
2338 if (!JS_WrapValue(cx
, ctorDesc
.value())) {
2339 return NS_ERROR_UNEXPECTED
;
2342 JS::Rooted
<JSObject
*> class_obj(cx
, &v
.toObject());
2344 const nsIID
*primary_iid
= &NS_GET_IID(nsISupports
);
2347 primary_iid
= &name_struct
->mIID
;
2349 else if (ci_data
->mProtoChainInterface
) {
2350 primary_iid
= ci_data
->mProtoChainInterface
;
2353 nsCOMPtr
<nsIInterfaceInfo
> if_info
;
2354 nsCOMPtr
<nsIInterfaceInfo
> parent
;
2355 const char *class_parent_name
= nullptr;
2357 if (!primary_iid
->Equals(NS_GET_IID(nsISupports
))) {
2358 JSAutoCompartment
ac(cx
, class_obj
);
2360 rv
= DefineInterfaceConstants(cx
, class_obj
, primary_iid
);
2361 NS_ENSURE_SUCCESS(rv
, rv
);
2363 nsCOMPtr
<nsIInterfaceInfoManager
>
2364 iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID
));
2365 NS_ENSURE_TRUE(iim
, NS_ERROR_NOT_AVAILABLE
);
2367 iim
->GetInfoForIID(primary_iid
, getter_AddRefs(if_info
));
2368 NS_ENSURE_TRUE(if_info
, NS_ERROR_UNEXPECTED
);
2370 const nsIID
*iid
= nullptr;
2372 if (ci_data
&& !ci_data
->mHasClassInterface
) {
2373 if_info
->GetIIDShared(&iid
);
2375 if_info
->GetParent(getter_AddRefs(parent
));
2376 NS_ENSURE_TRUE(parent
, NS_ERROR_UNEXPECTED
);
2378 parent
->GetIIDShared(&iid
);
2382 if (!iid
->Equals(NS_GET_IID(nsISupports
))) {
2383 if (ci_data
&& !ci_data
->mHasClassInterface
) {
2384 // If the class doesn't have a class interface the primary
2385 // interface is the interface that should be
2386 // constructor.prototype.__proto__.
2388 if_info
->GetNameShared(&class_parent_name
);
2390 // If the class does have a class interface (or there's no
2391 // real class for this name) then the parent of the
2392 // primary interface is what we want on
2393 // constructor.prototype.__proto__.
2395 NS_ASSERTION(parent
, "Whoa, this is bad, null parent here!");
2397 parent
->GetNameShared(&class_parent_name
);
2404 JS::Rooted
<JSObject
*> winobj(cx
, aWin
->FastGetGlobalJSObject());
2406 JS::Rooted
<JSObject
*> proto(cx
);
2408 if (class_parent_name
) {
2409 JSAutoCompartment
ac(cx
, winobj
);
2411 JS::Rooted
<JS::Value
> val(cx
);
2412 if (!JS_LookupProperty(cx
, winobj
, CutPrefix(class_parent_name
), &val
)) {
2413 return NS_ERROR_UNEXPECTED
;
2416 if (val
.isObject()) {
2417 JS::Rooted
<JSObject
*> obj(cx
, &val
.toObject());
2418 if (!JS_LookupProperty(cx
, obj
, "prototype", &val
)) {
2419 return NS_ERROR_UNEXPECTED
;
2422 if (val
.isObject()) {
2423 proto
= &val
.toObject();
2428 if (dot_prototype
) {
2429 JSAutoCompartment
ac(cx
, dot_prototype
);
2430 JS::Rooted
<JSObject
*> xpc_proto_proto(cx
);
2431 if (!::JS_GetPrototype(cx
, dot_prototype
, &xpc_proto_proto
)) {
2432 return NS_ERROR_UNEXPECTED
;
2436 (!xpc_proto_proto
||
2437 JS_GetClass(xpc_proto_proto
) == sObjectClass
)) {
2438 if (!JS_WrapObject(cx
, &proto
) ||
2439 !JS_SetPrototype(cx
, dot_prototype
, proto
)) {
2440 return NS_ERROR_UNEXPECTED
;
2444 JSAutoCompartment
ac(cx
, winobj
);
2446 proto
= JS_GetObjectPrototype(cx
, winobj
);
2448 dot_prototype
= ::JS_NewObjectWithUniqueType(cx
,
2449 &sDOMConstructorProtoClass
,
2452 NS_ENSURE_TRUE(dot_prototype
, NS_ERROR_OUT_OF_MEMORY
);
2456 v
= OBJECT_TO_JSVAL(dot_prototype
);
2458 JSAutoCompartment
ac(cx
, class_obj
);
2460 // Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly}
2461 if (!JS_WrapValue(cx
, &v
) ||
2462 !JS_DefineProperty(cx
, class_obj
, "prototype", v
,
2463 JSPROP_PERMANENT
| JSPROP_READONLY
,
2464 JS_PropertyStub
, JS_StrictPropertyStub
)) {
2465 return NS_ERROR_UNEXPECTED
;
2472 OldBindingConstructorEnabled(const nsGlobalNameStruct
*aStruct
,
2473 nsGlobalWindow
*aWin
, JSContext
*cx
)
2475 MOZ_ASSERT(aStruct
->mType
== nsGlobalNameStruct::eTypeProperty
||
2476 aStruct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
||
2477 aStruct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
);
2479 // Don't expose chrome only constructors to content windows.
2480 if (aStruct
->mChromeOnly
) {
2482 if (aStruct
->mAllowXBL
) {
2483 expose
= IsChromeOrXBL(cx
, nullptr);
2485 expose
= nsContentUtils::IsSystemPrincipal(aWin
->GetPrincipal());
2497 LookupComponentsShim(JSContext
*cx
, JS::Handle
<JSObject
*> global
,
2499 JS::MutableHandle
<JSPropertyDescriptor
> desc
);
2502 nsWindowSH::NameStructEnabled(JSContext
* aCx
, nsGlobalWindow
*aWin
,
2503 const nsAString
& aName
,
2504 const nsGlobalNameStruct
& aNameStruct
)
2506 const nsGlobalNameStruct
* nameStruct
= &aNameStruct
;
2507 if (nameStruct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfoCreator
) {
2508 nsresult rv
= GetExternalClassInfo(GetNameSpaceManager(), aName
, nameStruct
,
2510 if (NS_FAILED(rv
) || !nameStruct
) {
2515 return (nameStruct
->mType
!= nsGlobalNameStruct::eTypeProperty
&&
2516 nameStruct
->mType
!= nsGlobalNameStruct::eTypeClassConstructor
&&
2517 nameStruct
->mType
!= nsGlobalNameStruct::eTypeExternalClassInfo
) ||
2518 OldBindingConstructorEnabled(nameStruct
, aWin
, aCx
);
2521 #ifdef RELEASE_BUILD
2522 #define USE_CONTROLLERS_SHIM
2525 #ifdef USE_CONTROLLERS_SHIM
2526 static const JSClass ControllersShimClass
= {
2527 "XULControllers", 0,
2528 JS_PropertyStub
, JS_DeletePropertyStub
, JS_PropertyStub
, JS_StrictPropertyStub
,
2529 JS_EnumerateStub
, JS_ResolveStub
, JS_ConvertStub
, nullptr
2535 nsWindowSH::GlobalResolve(nsGlobalWindow
*aWin
, JSContext
*cx
,
2536 JS::Handle
<JSObject
*> obj
, JS::Handle
<jsid
> id
,
2537 JS::MutableHandle
<JSPropertyDescriptor
> desc
)
2539 if (id
== XPCJSRuntime::Get()->GetStringID(XPCJSRuntime::IDX_COMPONENTS
)) {
2540 return LookupComponentsShim(cx
, obj
, aWin
, desc
);
2543 #ifdef USE_CONTROLLERS_SHIM
2544 // Note: We use |obj| rather than |aWin| to get the principal here, because
2545 // this is called during Window setup when the Document isn't necessarily
2547 if (id
== XPCJSRuntime::Get()->GetStringID(XPCJSRuntime::IDX_CONTROLLERS
) &&
2548 !xpc::IsXrayWrapper(obj
) &&
2549 !nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj
)))
2551 if (aWin
->GetDoc()) {
2552 aWin
->GetDoc()->WarnOnceAbout(nsIDocument::eWindow_Controllers
);
2554 JS::Rooted
<JSObject
*> shim(cx
, JS_NewObject(cx
, &ControllersShimClass
, JS::NullPtr(), obj
));
2555 if (NS_WARN_IF(!shim
)) {
2556 return NS_ERROR_OUT_OF_MEMORY
;
2558 FillPropertyDescriptor(desc
, obj
, JS::ObjectValue(*shim
), /* readOnly = */ false);
2563 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
2564 NS_ENSURE_TRUE(nameSpaceManager
, NS_ERROR_NOT_INITIALIZED
);
2566 // Note - Our only caller is nsGlobalWindow::DoNewResolve, which checks that
2567 // JSID_IS_STRING(id) is true.
2568 nsAutoJSString name
;
2569 if (!name
.init(cx
, JSID_TO_STRING(id
))) {
2570 return NS_ERROR_OUT_OF_MEMORY
;
2573 const char16_t
*class_name
= nullptr;
2574 const nsGlobalNameStruct
*name_struct
=
2575 nameSpaceManager
->LookupName(name
, &class_name
);
2581 // The class_name had better match our name
2582 MOZ_ASSERT(name
.Equals(class_name
));
2584 NS_ENSURE_TRUE(class_name
, NS_ERROR_UNEXPECTED
);
2586 nsresult rv
= NS_OK
;
2588 if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfoCreator
) {
2589 rv
= GetExternalClassInfo(nameSpaceManager
, name
, name_struct
,
2591 if (NS_FAILED(rv
) || !name_struct
) {
2596 if (name_struct
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
||
2597 name_struct
->mType
== nsGlobalNameStruct::eTypeInterface
||
2598 name_struct
->mType
== nsGlobalNameStruct::eTypeClassProto
||
2599 name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2600 // Lookup new DOM bindings.
2601 DefineInterface getOrCreateInterfaceObject
=
2602 name_struct
->mDefineDOMInterface
;
2603 if (getOrCreateInterfaceObject
) {
2604 if (name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
&&
2605 !OldBindingConstructorEnabled(name_struct
, aWin
, cx
)) {
2609 ConstructorEnabled
* checkEnabledForScope
= name_struct
->mConstructorEnabled
;
2610 // We do the enabled check on the current compartment of cx, but for the
2611 // actual object we pass in the underlying object in the Xray case. That
2612 // way the callee can decide whether to allow access based on the caller
2613 // or the window being touched.
2614 JS::Rooted
<JSObject
*> global(cx
,
2615 js::CheckedUnwrap(obj
, /* stopAtOuter = */ false));
2617 return NS_ERROR_DOM_SECURITY_ERR
;
2619 if (checkEnabledForScope
&& !checkEnabledForScope(cx
, global
)) {
2623 // The DOM constructor resolve machinery interacts with Xrays in tricky
2624 // ways, and there are some asymmetries that are important to understand.
2626 // In the regular (non-Xray) case, we only want to resolve constructors
2627 // once (so that if they're deleted, they don't reappear). We do this by
2628 // stashing the constructor in a slot on the global, such that we can see
2629 // during resolve whether we've created it already. This is rather
2630 // memory-intensive, so we don't try to maintain these semantics when
2631 // manipulating a global over Xray (so the properties just re-resolve if
2632 // they've been deleted).
2634 // Unfortunately, there's a bit of an impedance-mismatch between the Xray
2635 // and non-Xray machinery. The Xray machinery wants an API that returns a
2636 // JSPropertyDescriptor, so that the resolve hook doesn't have to get
2637 // snared up with trying to define a property on the Xray holder. At the
2638 // same time, the DefineInterface callbacks are set up to define things
2639 // directly on the global. And re-jiggering them to return property
2640 // descriptors is tricky, because some DefineInterface callbacks define
2641 // multiple things (like the Image() alias for HTMLImageElement).
2643 // So the setup is as-follows:
2645 // * The resolve function takes a JSPropertyDescriptor, but in the
2646 // non-Xray case, callees may define things directly on the global, and
2647 // set the value on the property descriptor to |undefined| to indicate
2648 // that there's nothing more for the caller to do. We assert against
2649 // this behavior in the Xray case.
2651 // * We make sure that we do a non-Xray resolve first, so that all the
2652 // slots are set up. In the Xray case, this means unwrapping and doing
2653 // a non-Xray resolve before doing the Xray resolve.
2655 // This all could use some grand refactoring, but for now we just limp
2657 if (xpc::WrapperFactory::IsXrayWrapper(obj
)) {
2658 JS::Rooted
<JSObject
*> interfaceObject(cx
);
2660 JSAutoCompartment
ac(cx
, global
);
2661 interfaceObject
= getOrCreateInterfaceObject(cx
, global
, id
, false);
2663 if (NS_WARN_IF(!interfaceObject
)) {
2664 return NS_ERROR_FAILURE
;
2666 if (!JS_WrapObject(cx
, &interfaceObject
)) {
2667 return NS_ERROR_FAILURE
;
2670 FillPropertyDescriptor(desc
, obj
, 0, JS::ObjectValue(*interfaceObject
));
2672 JS::Rooted
<JSObject
*> interfaceObject(cx
,
2673 getOrCreateInterfaceObject(cx
, obj
, id
, true));
2674 if (NS_WARN_IF(!interfaceObject
)) {
2675 return NS_ERROR_FAILURE
;
2677 // We've already defined the property. We indicate this to the caller
2678 // by filling a property descriptor with JS::UndefinedValue() as the
2679 // value. We still have to fill in a property descriptor, though, so
2680 // that the caller knows the property is in fact on this object. It
2681 // doesn't matter what we pass for the "readonly" argument here.
2682 FillPropertyDescriptor(desc
, obj
, JS::UndefinedValue(), false);
2689 if (name_struct
->mType
== nsGlobalNameStruct::eTypeInterface
) {
2690 // We're resolving a name of a DOM interface for which there is no
2691 // direct DOM class, create a constructor object...
2692 nsRefPtr
<nsDOMConstructor
> constructor
;
2693 rv
= nsDOMConstructor::Create(class_name
,
2696 static_cast<nsPIDOMWindow
*>(aWin
),
2697 getter_AddRefs(constructor
));
2698 NS_ENSURE_SUCCESS(rv
, rv
);
2700 JS::Rooted
<JS::Value
> v(cx
);
2701 js::AssertSameCompartment(cx
, obj
);
2702 rv
= WrapNative(cx
, constructor
, &NS_GET_IID(nsIDOMDOMConstructor
),
2704 NS_ENSURE_SUCCESS(rv
, rv
);
2706 JS::Rooted
<JSObject
*> class_obj(cx
, &v
.toObject());
2708 // ... and define the constants from the DOM interface on that
2709 // constructor object.
2712 JSAutoCompartment
ac(cx
, class_obj
);
2713 rv
= DefineInterfaceConstants(cx
, class_obj
, &name_struct
->mIID
);
2714 NS_ENSURE_SUCCESS(rv
, rv
);
2717 if (!JS_WrapValue(cx
, &v
)) {
2718 return NS_ERROR_UNEXPECTED
;
2721 FillPropertyDescriptor(desc
, obj
, 0, v
);
2725 if (name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
||
2726 name_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
2727 if (!OldBindingConstructorEnabled(name_struct
, aWin
, cx
)) {
2731 // Create the XPConnect prototype for our classinfo, PostCreateProto will
2732 // set up the prototype chain. This will go ahead and define things on the
2733 // actual window's global.
2734 nsCOMPtr
<nsIXPConnectJSObjectHolder
> proto_holder
;
2735 rv
= GetXPCProto(sXPConnect
, cx
, aWin
, name_struct
,
2736 getter_AddRefs(proto_holder
));
2737 NS_ENSURE_SUCCESS(rv
, rv
);
2738 bool isXray
= xpc::WrapperFactory::IsXrayWrapper(obj
);
2739 MOZ_ASSERT_IF(obj
!= aWin
->GetGlobalJSObject(), isXray
);
2741 // GetXPCProto already defined the property for us
2742 FillPropertyDescriptor(desc
, obj
, JS::UndefinedValue(), false);
2746 // This is the Xray case. Look up the constructor object for this
2748 JS::Rooted
<JSObject
*> dot_prototype(cx
, proto_holder
->GetJSObject());
2749 NS_ENSURE_STATE(dot_prototype
);
2751 const nsDOMClassInfoData
*ci_data
;
2752 if (name_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2753 ci_data
= &sClassInfoData
[name_struct
->mDOMClassInfoID
];
2755 ci_data
= name_struct
->mData
;
2758 return ResolvePrototype(sXPConnect
, aWin
, cx
, obj
, class_name
, ci_data
,
2759 name_struct
, nameSpaceManager
, dot_prototype
,
2763 if (name_struct
->mType
== nsGlobalNameStruct::eTypeClassProto
) {
2764 // We don't have a XPConnect prototype object, let ResolvePrototype create
2766 return ResolvePrototype(sXPConnect
, aWin
, cx
, obj
, class_name
, nullptr,
2767 name_struct
, nameSpaceManager
, nullptr, desc
);
2770 if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalConstructorAlias
) {
2771 const nsGlobalNameStruct
*alias_struct
=
2772 nameSpaceManager
->GetConstructorProto(name_struct
);
2773 NS_ENSURE_TRUE(alias_struct
, NS_ERROR_UNEXPECTED
);
2775 // We need to use the XPConnect prototype for the DOM class that this
2776 // constructor is an alias for (for example for Image we need the prototype
2777 // for HTMLImageElement).
2778 nsCOMPtr
<nsIXPConnectJSObjectHolder
> proto_holder
;
2779 rv
= GetXPCProto(sXPConnect
, cx
, aWin
, alias_struct
,
2780 getter_AddRefs(proto_holder
));
2781 NS_ENSURE_SUCCESS(rv
, rv
);
2783 JSObject
* dot_prototype
= proto_holder
->GetJSObject();
2784 NS_ENSURE_STATE(dot_prototype
);
2786 const nsDOMClassInfoData
*ci_data
;
2787 if (alias_struct
->mType
== nsGlobalNameStruct::eTypeClassConstructor
) {
2788 ci_data
= &sClassInfoData
[alias_struct
->mDOMClassInfoID
];
2789 } else if (alias_struct
->mType
== nsGlobalNameStruct::eTypeExternalClassInfo
) {
2790 ci_data
= alias_struct
->mData
;
2792 return NS_ERROR_UNEXPECTED
;
2795 return ResolvePrototype(sXPConnect
, aWin
, cx
, obj
, class_name
, ci_data
,
2796 name_struct
, nameSpaceManager
, nullptr, desc
);
2799 if (name_struct
->mType
== nsGlobalNameStruct::eTypeExternalConstructor
) {
2800 nsRefPtr
<nsDOMConstructor
> constructor
;
2801 rv
= nsDOMConstructor::Create(class_name
, nullptr, name_struct
,
2802 static_cast<nsPIDOMWindow
*>(aWin
),
2803 getter_AddRefs(constructor
));
2804 NS_ENSURE_SUCCESS(rv
, rv
);
2806 JS::Rooted
<JS::Value
> val(cx
);
2807 js::AssertSameCompartment(cx
, obj
);
2808 rv
= WrapNative(cx
, constructor
, &NS_GET_IID(nsIDOMDOMConstructor
),
2810 NS_ENSURE_SUCCESS(rv
, rv
);
2812 NS_ASSERTION(val
.isObject(), "Why didn't we get a JSObject?");
2814 FillPropertyDescriptor(desc
, obj
, 0, val
);
2819 if (name_struct
->mType
== nsGlobalNameStruct::eTypeProperty
) {
2820 if (!OldBindingConstructorEnabled(name_struct
, aWin
, cx
))
2823 // Before defining a global property, check for a named subframe of the
2824 // same name. If it exists, we don't want to shadow it.
2825 nsCOMPtr
<nsIDOMWindow
> childWin
= aWin
->GetChildWindow(name
);
2829 nsCOMPtr
<nsISupports
> native(do_CreateInstance(name_struct
->mCID
, &rv
));
2830 NS_ENSURE_SUCCESS(rv
, rv
);
2832 JS::Rooted
<JS::Value
> prop_val(cx
, JS::UndefinedValue()); // Property value.
2834 nsCOMPtr
<nsIDOMGlobalPropertyInitializer
> gpi(do_QueryInterface(native
));
2836 rv
= gpi
->Init(aWin
, &prop_val
);
2837 NS_ENSURE_SUCCESS(rv
, rv
);
2840 if (prop_val
.isPrimitive() && !prop_val
.isNull()) {
2841 if (aWin
->IsOuterWindow()) {
2842 nsGlobalWindow
*inner
= aWin
->GetCurrentInnerWindowInternal();
2843 NS_ENSURE_TRUE(inner
, NS_ERROR_UNEXPECTED
);
2846 rv
= WrapNative(cx
, native
, true, &prop_val
);
2849 NS_ENSURE_SUCCESS(rv
, rv
);
2851 if (!JS_WrapValue(cx
, &prop_val
)) {
2852 return NS_ERROR_UNEXPECTED
;
2855 FillPropertyDescriptor(desc
, obj
, prop_val
, false);
2863 template<class Interface
>
2865 LocationSetterGuts(JSContext
*cx
, JSObject
*obj
, JS::MutableHandle
<JS::Value
> vp
)
2867 // This function duplicates some of the logic in XPC_WN_HelperSetProperty
2868 obj
= js::CheckedUnwrap(obj
, /* stopAtOuter = */ false);
2869 if (!IS_WN_REFLECTOR(obj
))
2870 return NS_ERROR_XPC_BAD_CONVERT_JS
;
2871 XPCWrappedNative
*wrapper
= XPCWrappedNative::Get(obj
);
2873 // The error checks duplicate code in THROW_AND_RETURN_IF_BAD_WRAPPER
2874 NS_ENSURE_TRUE(!wrapper
|| wrapper
->IsValid(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN
);
2876 nsCOMPtr
<Interface
> xpcomObj
= do_QueryWrappedNative(wrapper
, obj
);
2877 NS_ENSURE_TRUE(xpcomObj
, NS_ERROR_UNEXPECTED
);
2879 nsCOMPtr
<nsIDOMLocation
> location
;
2880 nsresult rv
= xpcomObj
->GetLocation(getter_AddRefs(location
));
2881 NS_ENSURE_SUCCESS(rv
, rv
);
2883 // Grab the value we're being set to before we stomp on |vp|
2884 JS::Rooted
<JSString
*> val(cx
, JS::ToString(cx
, vp
));
2885 NS_ENSURE_TRUE(val
, NS_ERROR_UNEXPECTED
);
2887 // Make sure |val| stays alive below
2888 JS::Anchor
<JSString
*> anchor(val
);
2890 // We have to wrap location into vp before null-checking location, to
2891 // avoid assigning the wrong thing into the slot.
2892 rv
= WrapNative(cx
, location
, &NS_GET_IID(nsIDOMLocation
), true, vp
);
2893 NS_ENSURE_SUCCESS(rv
, rv
);
2896 // Make this a no-op
2901 NS_ENSURE_TRUE(str
.init(cx
, val
), NS_ERROR_UNEXPECTED
);
2903 return location
->SetHref(str
);
2906 template<class Interface
>
2908 LocationSetter(JSContext
*cx
, JS::Handle
<JSObject
*> obj
, JS::Handle
<jsid
> id
, bool strict
,
2909 JS::MutableHandle
<JS::Value
> vp
)
2911 nsresult rv
= LocationSetterGuts
<Interface
>(cx
, obj
, vp
);
2912 if (NS_FAILED(rv
)) {
2921 LocationSetterUnwrapper(JSContext
*cx
, JS::Handle
<JSObject
*> obj_
, JS::Handle
<jsid
> id
,
2922 bool strict
, JS::MutableHandle
<JS::Value
> vp
)
2924 JS::Rooted
<JSObject
*> obj(cx
, obj_
);
2926 JSObject
*wrapped
= XPCWrapper::UnsafeUnwrapSecurityWrapper(obj
);
2931 return LocationSetter
<nsIDOMWindow
>(cx
, obj
, id
, strict
, vp
);
2934 struct InterfaceShimEntry
{
2935 const char *geckoName
;
2936 const char *domName
;
2939 // We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
2940 // interface that has interface constants that sites might be getting off
2942 const InterfaceShimEntry kInterfaceShimMap
[] =
2943 { { "nsIDOMFileReader", "FileReader" },
2944 { "nsIXMLHttpRequest", "XMLHttpRequest" },
2945 { "nsIDOMDOMException", "DOMException" },
2946 { "nsIDOMNode", "Node" },
2947 { "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
2948 { "nsIDOMCSSRule", "CSSRule" },
2949 { "nsIDOMCSSValue", "CSSValue" },
2950 { "nsIDOMEvent", "Event" },
2951 { "nsIDOMNSEvent", "Event" },
2952 { "nsIDOMKeyEvent", "KeyEvent" },
2953 { "nsIDOMMouseEvent", "MouseEvent" },
2954 { "nsIDOMMouseScrollEvent", "MouseScrollEvent" },
2955 { "nsIDOMMutationEvent", "MutationEvent" },
2956 { "nsIDOMSimpleGestureEvent", "SimpleGestureEvent" },
2957 { "nsIDOMUIEvent", "UIEvent" },
2958 { "nsIDOMHTMLMediaElement", "HTMLMediaElement" },
2959 { "nsIDOMMediaError", "MediaError" },
2960 { "nsIDOMOfflineResourceList", "OfflineResourceList" },
2961 { "nsIDOMRange", "Range" },
2962 { "nsIDOMSVGLength", "SVGLength" },
2963 { "nsIDOMNodeFilter", "NodeFilter" },
2964 { "nsIDOMXPathResult", "XPathResult" } };
2967 LookupComponentsShim(JSContext
*cx
, JS::Handle
<JSObject
*> global
,
2969 JS::MutableHandle
<JSPropertyDescriptor
> desc
)
2971 // Keep track of how often this happens.
2972 Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT
, true);
2975 nsCOMPtr
<nsIDocument
> doc
= win
->GetExtantDoc();
2977 doc
->WarnOnceAbout(nsIDocument::eComponents
, /* asError = */ true);
2980 // Create a fake Components object.
2981 JS::Rooted
<JSObject
*> components(cx
, JS_NewObject(cx
, nullptr, JS::NullPtr(), global
));
2982 NS_ENSURE_TRUE(components
, NS_ERROR_OUT_OF_MEMORY
);
2984 // Create a fake interfaces object.
2985 JS::Rooted
<JSObject
*> interfaces(cx
, JS_NewObject(cx
, nullptr, JS::NullPtr(), global
));
2986 NS_ENSURE_TRUE(interfaces
, NS_ERROR_OUT_OF_MEMORY
);
2988 JS_DefineProperty(cx
, components
, "interfaces", interfaces
,
2989 JSPROP_ENUMERATE
| JSPROP_PERMANENT
| JSPROP_READONLY
,
2990 JS_PropertyStub
, JS_StrictPropertyStub
);
2991 NS_ENSURE_TRUE(ok
, NS_ERROR_OUT_OF_MEMORY
);
2993 // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
2994 // interfaces with constants.
2995 for (uint32_t i
= 0; i
< ArrayLength(kInterfaceShimMap
); ++i
) {
2997 // Grab the names from the table.
2998 const char *geckoName
= kInterfaceShimMap
[i
].geckoName
;
2999 const char *domName
= kInterfaceShimMap
[i
].domName
;
3001 // Look up the appopriate interface object on the global.
3002 JS::Rooted
<JS::Value
> v(cx
, JS::UndefinedValue());
3003 ok
= JS_GetProperty(cx
, global
, domName
, &v
);
3004 NS_ENSURE_TRUE(ok
, NS_ERROR_OUT_OF_MEMORY
);
3005 if (!v
.isObject()) {
3006 NS_WARNING("Unable to find interface object on global");
3010 // Define the shim on the interfaces object.
3011 ok
= JS_DefineProperty(cx
, interfaces
, geckoName
, v
,
3012 JSPROP_ENUMERATE
| JSPROP_PERMANENT
| JSPROP_READONLY
,
3013 JS_PropertyStub
, JS_StrictPropertyStub
);
3014 NS_ENSURE_TRUE(ok
, NS_ERROR_OUT_OF_MEMORY
);
3017 FillPropertyDescriptor(desc
, global
, JS::ObjectValue(*components
), false);
3023 nsWindowSH::NewResolve(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
3024 JSObject
*obj_
, jsid id_
, JSObject
**objp
,
3027 JS::Rooted
<JSObject
*> obj(cx
, obj_
);
3028 JS::Rooted
<jsid
> id(cx
, id_
);
3030 if (!JSID_IS_STRING(id
)) {
3034 MOZ_ASSERT(*_retval
== true); // guaranteed by XPC_WN_Helper_NewResolve
3036 nsGlobalWindow
*win
= nsGlobalWindow::FromWrapper(wrapper
);
3037 MOZ_ASSERT(win
->IsInnerWindow());
3039 // Don't resolve standard classes on XrayWrappers, only resolve them if we're
3040 // resolving on the real global object.
3041 bool isXray
= xpc::WrapperFactory::IsXrayWrapper(obj
);
3043 bool did_resolve
= false;
3044 if (!JS_ResolveStandardClass(cx
, obj
, id
, &did_resolve
)) {
3045 // Return NS_OK to avoid stomping over the exception that was passed
3046 // down from the ResolveStandardClass call.
3057 // WebIDL quickstubs handle location for us, but Xrays don't see those. So if
3058 // we're an Xray, we have to resolve stuff here to make "window.location =
3059 // someString" work.
3060 if (sLocation_id
== id
&& isXray
) {
3061 nsCOMPtr
<nsIDOMLocation
> location
;
3062 nsresult rv
= win
->GetLocation(getter_AddRefs(location
));
3063 NS_ENSURE_SUCCESS(rv
, rv
);
3065 JS::Rooted
<JS::Value
> v(cx
);
3066 rv
= WrapNative(cx
, location
, &NS_GET_IID(nsIDOMLocation
), true, &v
);
3067 NS_ENSURE_SUCCESS(rv
, rv
);
3069 bool ok
= JS_DefinePropertyById(cx
, obj
, id
, v
,
3070 JSPROP_PERMANENT
| JSPROP_ENUMERATE
,
3071 JS_PropertyStub
, LocationSetterUnwrapper
);
3074 return NS_ERROR_FAILURE
;
3082 // WebIDL quickstubs handle "top" for us, but Xrays don't see those. So if
3083 // we're an Xray and we want "top" to be JSPROP_PERMANENT, we need to resolve
3085 if (sTop_id
== id
&& isXray
) {
3086 nsCOMPtr
<nsIDOMWindow
> top
;
3087 nsresult rv
= win
->GetScriptableTop(getter_AddRefs(top
));
3088 NS_ENSURE_SUCCESS(rv
, rv
);
3090 JS::Rooted
<JS::Value
> v(cx
);
3091 js::AssertSameCompartment(cx
, obj
);
3092 rv
= WrapNative(cx
, top
, &NS_GET_IID(nsIDOMWindow
), true, &v
);
3093 NS_ENSURE_SUCCESS(rv
, rv
);
3095 // Hold on to the top window object as a global property so we
3096 // don't need to worry about losing expando properties etc.
3097 if (!JS_DefinePropertyById(cx
, obj
, id
, v
,
3098 JSPROP_READONLY
| JSPROP_PERMANENT
|
3100 JS_PropertyStub
, JS_StrictPropertyStub
)) {
3101 return NS_ERROR_FAILURE
;
3109 // We promise to resolve on the underlying object first. That will create
3110 // the actual interface object if needed and store it in a data structure
3111 // hanging off the global. Then our second call will wrap up in an Xray as
3112 // needed. We do things this way because we use the existence of the
3113 // object in that data structure as a flag that indicates that its name
3114 // (and any relevant named constructor names) has been resolved before;
3115 // this allows us to avoid re-resolving in the Xray case if the property is
3116 // deleted by page script.
3117 JS::Rooted
<JSObject
*> global(cx
,
3118 js::UncheckedUnwrap(obj
, /* stopAtOuter = */ false));
3119 JSAutoCompartment
ac(cx
, global
);
3120 JS::Rooted
<JSPropertyDescriptor
> desc(cx
);
3121 if (!win
->DoNewResolve(cx
, global
, id
, &desc
)) {
3122 return NS_ERROR_FAILURE
;
3124 // If we have an object here, that means we resolved the property.
3125 // But if the value is undefined, that means that GlobalResolve
3126 // also already defined it, so we don't have to.
3127 if (desc
.object() && !desc
.value().isUndefined() &&
3128 !JS_DefinePropertyById(cx
, global
, id
, desc
.value(),
3130 desc
.getter(), desc
.setter())) {
3131 return NS_ERROR_FAILURE
;
3135 JS::Rooted
<JSPropertyDescriptor
> desc(cx
);
3136 if (!win
->DoNewResolve(cx
, obj
, id
, &desc
)) {
3137 return NS_ERROR_FAILURE
;
3139 if (desc
.object()) {
3140 // If we have an object here, that means we resolved the property.
3141 // But if the value is undefined, that means that GlobalResolve
3142 // also already defined it, so we don't have to. Note that in the
3143 // Xray case we should never see undefined.
3144 MOZ_ASSERT_IF(isXray
, !desc
.value().isUndefined());
3145 if (!desc
.value().isUndefined() &&
3146 !JS_DefinePropertyById(cx
, obj
, id
, desc
.value(),
3148 desc
.getter(), desc
.setter())) {
3149 return NS_ERROR_FAILURE
;
3156 if (sDocument_id
== id
) {
3157 nsCOMPtr
<nsIDocument
> document
= win
->GetDoc();
3158 JS::Rooted
<JS::Value
> v(cx
);
3159 nsresult rv
= WrapNative(cx
, document
, document
,
3160 &NS_GET_IID(nsIDOMDocument
), &v
, false);
3161 NS_ENSURE_SUCCESS(rv
, rv
);
3163 // nsIDocument::WrapObject will handle defining the property.
3166 // NB: We need to do this for any Xray wrapper.
3167 if (xpc::WrapperFactory::IsXrayWrapper(obj
)) {
3168 *_retval
= JS_WrapValue(cx
, &v
) &&
3169 JS_DefineProperty(cx
, obj
, "document", v
,
3170 JSPROP_READONLY
| JSPROP_ENUMERATE
,
3171 JS_PropertyStub
, JS_StrictPropertyStub
);
3173 return NS_ERROR_UNEXPECTED
;
3180 return nsDOMGenericSH::NewResolve(wrapper
, cx
, obj
, id
, objp
, _retval
);
3184 nsWindowSH::OuterObject(nsIXPConnectWrappedNative
*wrapper
, JSContext
* cx
,
3185 JSObject
* obj
, JSObject
* *_retval
)
3187 nsGlobalWindow
*origWin
= nsGlobalWindow::FromWrapper(wrapper
);
3188 nsGlobalWindow
*win
= origWin
->GetOuterWindowInternal();
3191 // If we no longer have an outer window. No code should ever be
3192 // running on a window w/o an outer, which means this hook should
3193 // never be called when we have no outer. But just in case, return
3194 // null to prevent leaking an inner window to code in a different
3197 return NS_ERROR_UNEXPECTED
;
3200 JS::Rooted
<JSObject
*> winObj(cx
, win
->FastGetGlobalJSObject());
3203 // Note that while |wrapper| is same-compartment with cx, the outer window
3204 // might not be. If we're running script in an inactive scope and evalute
3205 // |this|, the outer window is actually a cross-compartment wrapper. So we
3206 // need to wrap here.
3207 if (!JS_WrapObject(cx
, &winObj
)) {
3209 return NS_ERROR_UNEXPECTED
;
3216 // EventTarget helper
3219 nsEventTargetSH::PreCreate(nsISupports
*nativeObj
, JSContext
*cx
,
3220 JSObject
*aGlobalObj
, JSObject
**parentObj
)
3222 JS::Rooted
<JSObject
*> globalObj(cx
, aGlobalObj
);
3223 DOMEventTargetHelper
* target
= DOMEventTargetHelper::FromSupports(nativeObj
);
3225 nsCOMPtr
<nsIScriptGlobalObject
> native_parent
;
3226 target
->GetParentObject(getter_AddRefs(native_parent
));
3228 *parentObj
= native_parent
? native_parent
->GetGlobalJSObject() : globalObj
;
3230 return *parentObj
? NS_OK
: NS_ERROR_FAILURE
;
3234 nsEventTargetSH::AddProperty(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
3235 JSObject
*obj
, jsid id
, jsval
*vp
, bool *_retval
)
3237 nsEventTargetSH::PreserveWrapper(GetNative(wrapper
, obj
));
3243 nsEventTargetSH::PreserveWrapper(nsISupports
*aNative
)
3245 DOMEventTargetHelper
* target
= DOMEventTargetHelper::FromSupports(aNative
);
3246 target
->PreserveWrapper(aNative
);
3249 // nsIDOMEventListener::HandleEvent() 'this' converter helper
3251 NS_INTERFACE_MAP_BEGIN(nsEventListenerThisTranslator
)
3252 NS_INTERFACE_MAP_ENTRY(nsIXPCFunctionThisTranslator
)
3253 NS_INTERFACE_MAP_ENTRY(nsISupports
)
3254 NS_INTERFACE_MAP_END
3257 NS_IMPL_ADDREF(nsEventListenerThisTranslator
)
3258 NS_IMPL_RELEASE(nsEventListenerThisTranslator
)
3262 nsEventListenerThisTranslator::TranslateThis(nsISupports
*aInitialThis
,
3263 nsISupports
**_retval
)
3265 nsCOMPtr
<nsIDOMEvent
> event(do_QueryInterface(aInitialThis
));
3266 NS_ENSURE_TRUE(event
, NS_ERROR_UNEXPECTED
);
3268 nsCOMPtr
<EventTarget
> target
= event
->InternalDOMEvent()->GetCurrentTarget();
3269 target
.forget(_retval
);
3274 nsDOMConstructorSH::PreCreate(nsISupports
*nativeObj
, JSContext
*cx
,
3275 JSObject
*aGlobalObj
, JSObject
**parentObj
)
3277 JS::Rooted
<JSObject
*> globalObj(cx
, aGlobalObj
);
3278 nsDOMConstructor
*wrapped
= static_cast<nsDOMConstructor
*>(nativeObj
);
3282 nsCOMPtr
<nsIDOMDOMConstructor
> is_constructor
=
3283 do_QueryInterface(nativeObj
);
3284 NS_ASSERTION(is_constructor
, "How did we not get a constructor?");
3288 return wrapped
->PreCreate(cx
, globalObj
, parentObj
);
3292 nsDOMConstructorSH::NewResolve(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
3293 JSObject
*aObj
, jsid aId
, JSObject
**objp
,
3296 JS::Rooted
<JSObject
*> obj(cx
, aObj
);
3297 JS::Rooted
<jsid
> id(cx
, aId
);
3298 // For regular DOM constructors, we have our interface constants defined on
3299 // us by nsWindowSH::GlobalResolve. However, XrayWrappers can't see these
3300 // interface constants (as they look like expando properties) so we have to
3301 // specially resolve those constants here, but only for Xray wrappers.
3302 if (!ObjectIsNativeWrapper(cx
, obj
)) {
3306 JS::Rooted
<JSObject
*> nativePropsObj(cx
, xpc::XrayUtils::GetNativePropertiesObject(cx
, obj
));
3307 nsDOMConstructor
*wrapped
=
3308 static_cast<nsDOMConstructor
*>(wrapper
->Native());
3309 nsresult rv
= wrapped
->ResolveInterfaceConstants(cx
, nativePropsObj
);
3310 NS_ENSURE_SUCCESS(rv
, rv
);
3312 // Now re-lookup the ID to see if we should report back that we resolved the
3313 // looked-for constant. Note that we don't have to worry about infinitely
3314 // recurring back here because the Xray wrapper's holder object doesn't call
3315 // NewResolve hooks.
3317 if (!JS_HasPropertyById(cx
, nativePropsObj
, id
, &found
)) {
3329 nsDOMConstructorSH::Call(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
3330 JSObject
*aObj
, const JS::CallArgs
&args
, bool *_retval
)
3332 JS::Rooted
<JSObject
*> obj(cx
, aObj
);
3335 nsDOMConstructor
*wrapped
=
3336 static_cast<nsDOMConstructor
*>(wrapper
->Native());
3340 nsCOMPtr
<nsIDOMDOMConstructor
> is_constructor
=
3341 do_QueryWrappedNative(wrapper
);
3342 NS_ASSERTION(is_constructor
, "How did we not get a constructor?");
3346 return wrapped
->Construct(wrapper
, cx
, obj
, args
, _retval
);
3350 nsDOMConstructorSH::Construct(nsIXPConnectWrappedNative
*wrapper
, JSContext
*cx
,
3351 JSObject
*aObj
, const JS::CallArgs
&args
, bool *_retval
)
3353 JS::Rooted
<JSObject
*> obj(cx
, aObj
);
3356 nsDOMConstructor
*wrapped
=
3357 static_cast<nsDOMConstructor
*>(wrapper
->Native());
3361 nsCOMPtr
<nsIDOMDOMConstructor
> is_constructor
=
3362 do_QueryWrappedNative(wrapper
);
3363 NS_ASSERTION(is_constructor
, "How did we not get a constructor?");
3367 return wrapped
->Construct(wrapper
, cx
, obj
, args
, _retval
);
3371 nsDOMConstructorSH::HasInstance(nsIXPConnectWrappedNative
*wrapper
,
3372 JSContext
*cx
, JSObject
*aObj
, JS::Handle
<JS::Value
> val
,
3373 bool *bp
, bool *_retval
)
3375 JS::Rooted
<JSObject
*> obj(cx
, aObj
);
3376 nsDOMConstructor
*wrapped
=
3377 static_cast<nsDOMConstructor
*>(wrapper
->Native());
3381 nsCOMPtr
<nsIDOMDOMConstructor
> is_constructor
=
3382 do_QueryWrappedNative(wrapper
);
3383 NS_ASSERTION(is_constructor
, "How did we not get a constructor?");
3387 return wrapped
->HasInstance(wrapper
, cx
, obj
, val
, bp
, _retval
);
3391 nsNonDOMObjectSH::GetFlags(uint32_t *aFlags
)
3393 // This is NOT a DOM Object. Use this helper class for cases when you need
3394 // to do something like implement nsISecurityCheckedComponent in a meaningful
3396 *aFlags
= nsIClassInfo::MAIN_THREAD_ONLY
| nsIClassInfo::SINGLETON_CLASSINFO
;