dom/base/nsDOMClassInfo.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:4084ea047276
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef nsDOMClassInfo_h___
8 #define nsDOMClassInfo_h___
9
10 #include "mozilla/Attributes.h"
11 #include "nsIXPCScriptable.h"
12 #include "nsIScriptGlobalObject.h"
13 #include "nsIDOMScriptObjectFactory.h"
14 #include "js/Id.h"
15 #include "nsIXPConnect.h"
16
17 #ifdef XP_WIN
18 #undef GetClassName
19 #endif
20
21 class nsContentList;
22 class nsDocument;
23 struct nsGlobalNameStruct;
24 class nsGlobalWindow;
25 class nsIScriptSecurityManager;
26
27 struct nsDOMClassInfoData;
28
29 typedef nsIClassInfo* (*nsDOMClassInfoConstructorFnc)
30 (nsDOMClassInfoData* aData);
31
32 typedef nsresult (*nsDOMConstructorFunc)(nsISupports** aNewObject);
33
34 struct nsDOMClassInfoData
35 {
36 const char *mName;
37 const char16_t *mNameUTF16;
38 union {
39 nsDOMClassInfoConstructorFnc mConstructorFptr;
40 nsDOMClassInfoExternalConstructorFnc mExternalConstructorFptr;
41 } u;
42
43 nsIClassInfo *mCachedClassInfo; // low bit is set to 1 if external,
44 // so be sure to mask if necessary!
45 const nsIID *mProtoChainInterface;
46 const nsIID **mInterfaces;
47 uint32_t mScriptableFlags : 31; // flags must not use more than 31 bits!
48 uint32_t mHasClassInterface : 1;
49 uint32_t mInterfacesBitmap;
50 bool mChromeOnly : 1;
51 bool mAllowXBL : 1;
52 bool mDisabled : 1;
53 #ifdef DEBUG
54 uint32_t mDebugID;
55 #endif
56 };
57
58 struct nsExternalDOMClassInfoData : public nsDOMClassInfoData
59 {
60 const nsCID *mConstructorCID;
61 };
62
63
64 // To be used with the nsDOMClassInfoData::mCachedClassInfo pointer.
65 // The low bit is set when we created a generic helper for an external
66 // (which holds on to the nsDOMClassInfoData).
67 #define GET_CLEAN_CI_PTR(_ptr) (nsIClassInfo*)(uintptr_t(_ptr) & ~0x1)
68 #define MARK_EXTERNAL(_ptr) (nsIClassInfo*)(uintptr_t(_ptr) | 0x1)
69 #define IS_EXTERNAL(_ptr) (uintptr_t(_ptr) & 0x1)
70
71
72 class nsDOMClassInfo : public nsXPCClassInfo
73 {
74 friend class nsHTMLDocumentSH;
75 public:
76 nsDOMClassInfo(nsDOMClassInfoData* aData);
77 virtual ~nsDOMClassInfo();
78
79 NS_DECL_NSIXPCSCRIPTABLE
80
81 NS_DECL_ISUPPORTS
82
83 NS_DECL_NSICLASSINFO
84
85 // Helper method that returns a *non* refcounted pointer to a
86 // helper. So please note, don't release this pointer, if you do,
87 // you better make sure you've addreffed before release.
88 //
89 // Whaaaaa! I wanted to name this method GetClassInfo, but nooo,
90 // some of Microsoft devstudio's headers #defines GetClassInfo to
91 // GetClassInfoA so I can't, those $%#@^! bastards!!! What gives
92 // them the right to do that?
93
94 static nsIClassInfo* GetClassInfoInstance(nsDOMClassInfoData* aData);
95
96 static void ShutDown();
97
98 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
99 {
100 return new nsDOMClassInfo(aData);
101 }
102
103 /*
104 * The following two functions exist because of the way that Xray wrappers
105 * work. In order to allow scriptable helpers to define non-IDL defined but
106 * still "safe" properties for Xray wrappers, we call into the scriptable
107 * helper with |obj| being the wrapper.
108 *
109 * Ideally, that would be the end of the story, however due to complications
110 * dealing with document.domain, it's possible to end up in a scriptable
111 * helper with a wrapper, even though we should be treating the lookup as a
112 * transparent one.
113 *
114 * Note: So ObjectIsNativeWrapper(cx, obj) check usually means "through xray
115 * wrapper this part is not visible" while combined with
116 * || xpc::WrapperFactory::XrayWrapperNotShadowing(obj) it means "through
117 * xray wrapper it is visible only if it does not hide any native property."
118 */
119 static bool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj);
120
121 static nsISupports *GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj);
122
123 static nsIXPConnect *XPConnect()
124 {
125 return sXPConnect;
126 }
127 static nsIScriptSecurityManager *ScriptSecurityManager()
128 {
129 return sSecMan;
130 }
131
132 protected:
133 friend nsIClassInfo* NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
134
135 const nsDOMClassInfoData* mData;
136
137 virtual void PreserveWrapper(nsISupports *aNative) MOZ_OVERRIDE
138 {
139 }
140
141 virtual uint32_t GetInterfacesBitmap() MOZ_OVERRIDE
142 {
143 return mData->mInterfacesBitmap;
144 }
145
146 static nsresult Init();
147 static nsresult RegisterClassProtos(int32_t aDOMClassInfoID);
148 static nsresult RegisterExternalClasses();
149 nsresult ResolveConstructor(JSContext *cx, JSObject *obj,
150 JSObject **objp);
151
152 // Checks if id is a number and returns the number, if aIsNumber is
153 // non-null it's set to true if the id is a number and false if it's
154 // not a number. If id is not a number this method returns -1
155 static int32_t GetArrayIndexFromId(JSContext *cx, JS::Handle<jsid> id,
156 bool *aIsNumber = nullptr);
157
158 static nsIXPConnect *sXPConnect;
159 static nsIScriptSecurityManager *sSecMan;
160
161 // nsIXPCScriptable code
162 static nsresult DefineStaticJSVals(JSContext *cx);
163
164 static bool sIsInitialized;
165
166 public:
167 static jsid sLocation_id;
168 static jsid sConstructor_id;
169 static jsid sLength_id;
170 static jsid sItem_id;
171 static jsid sNamedItem_id;
172 static jsid sEnumerate_id;
173 static jsid sTop_id;
174 static jsid sDocument_id;
175 static jsid sWrappedJSObject_id;
176 };
177
178 // THIS ONE ISN'T SAFE!! It assumes that the private of the JSObject is
179 // an nsISupports.
180 inline
181 const nsQueryInterface
182 do_QueryWrappedNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj)
183 {
184 return nsQueryInterface(nsDOMClassInfo::GetNative(wrapper, obj));
185 }
186
187 // THIS ONE ISN'T SAFE!! It assumes that the private of the JSObject is
188 // an nsISupports.
189 inline
190 const nsQueryInterfaceWithError
191 do_QueryWrappedNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj,
192 nsresult *aError)
193
194 {
195 return nsQueryInterfaceWithError(nsDOMClassInfo::GetNative(wrapper, obj),
196 aError);
197 }
198
199 inline
200 nsQueryInterface
201 do_QueryWrapper(JSContext *cx, JSObject *obj)
202 {
203 nsISupports *native =
204 nsDOMClassInfo::XPConnect()->GetNativeOfWrapper(cx, obj);
205 return nsQueryInterface(native);
206 }
207
208 inline
209 nsQueryInterfaceWithError
210 do_QueryWrapper(JSContext *cx, JSObject *obj, nsresult* error)
211 {
212 nsISupports *native =
213 nsDOMClassInfo::XPConnect()->GetNativeOfWrapper(cx, obj);
214 return nsQueryInterfaceWithError(native, error);
215 }
216
217
218 typedef nsDOMClassInfo nsDOMGenericSH;
219
220 // Makes sure that the wrapper is preserved if new properties are added.
221 class nsEventTargetSH : public nsDOMGenericSH
222 {
223 protected:
224 nsEventTargetSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
225 {
226 }
227
228 virtual ~nsEventTargetSH()
229 {
230 }
231 public:
232 NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
233 JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
234 NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
235 JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
236
237 virtual void PreserveWrapper(nsISupports *aNative) MOZ_OVERRIDE;
238
239 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
240 {
241 return new nsEventTargetSH(aData);
242 }
243 };
244
245 // Window scriptable helper
246
247 class nsWindowSH : public nsDOMGenericSH
248 {
249 protected:
250 nsWindowSH(nsDOMClassInfoData *aData) : nsDOMGenericSH(aData)
251 {
252 }
253
254 virtual ~nsWindowSH()
255 {
256 }
257
258 static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
259 JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
260 JS::MutableHandle<JSPropertyDescriptor> desc);
261
262 friend class nsGlobalWindow;
263 public:
264 NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
265 JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
266 NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) MOZ_OVERRIDE;
267 NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
268 JSObject *obj) MOZ_OVERRIDE;
269 NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
270 JSObject *obj, bool *_retval) MOZ_OVERRIDE;
271 NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
272 JSObject *obj, jsid id, JSObject **objp,
273 bool *_retval) MOZ_OVERRIDE;
274 NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
275 JSObject * obj, JSObject * *_retval) MOZ_OVERRIDE;
276
277 static bool NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin,
278 const nsAString& aName,
279 const nsGlobalNameStruct& aNameStruct);
280
281 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
282 {
283 return new nsWindowSH(aData);
284 }
285 };
286
287 // Location scriptable helper
288
289 class nsLocationSH : public nsDOMGenericSH
290 {
291 protected:
292 nsLocationSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
293 {
294 }
295
296 virtual ~nsLocationSH()
297 {
298 }
299
300 public:
301 NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
302 JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
303 NS_IMETHODIMP AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
304 JSObject *obj, jsid id, JS::Value *vp, bool *_retval);
305
306 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
307 {
308 return new nsLocationSH(aData);
309 }
310 };
311
312
313 // Generic array scriptable helper
314
315 class nsGenericArraySH : public nsDOMClassInfo
316 {
317 protected:
318 nsGenericArraySH(nsDOMClassInfoData* aData) : nsDOMClassInfo(aData)
319 {
320 }
321
322 virtual ~nsGenericArraySH()
323 {
324 }
325
326 public:
327 NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
328 JSObject *obj, jsid id, JSObject **objp,
329 bool *_retval) MOZ_OVERRIDE;
330 NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
331 JSObject *obj, bool *_retval) MOZ_OVERRIDE;
332
333 virtual nsresult GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
334 JS::Handle<JSObject*> obj, uint32_t *length);
335
336 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
337 {
338 return new nsGenericArraySH(aData);
339 }
340 };
341
342
343 // Array scriptable helper
344
345 class nsArraySH : public nsGenericArraySH
346 {
347 protected:
348 nsArraySH(nsDOMClassInfoData* aData) : nsGenericArraySH(aData)
349 {
350 }
351
352 virtual ~nsArraySH()
353 {
354 }
355
356 // Subclasses need to override this, if the implementation can't fail it's
357 // allowed to not set *aResult.
358 virtual nsISupports* GetItemAt(nsISupports *aNative, uint32_t aIndex,
359 nsWrapperCache **aCache, nsresult *aResult) = 0;
360
361 public:
362 NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
363 JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
364
365 private:
366 // Not implemented, nothing should create an instance of this class.
367 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData);
368 };
369
370
371 // CSSRuleList helper
372
373 class nsCSSRuleListSH : public nsArraySH
374 {
375 protected:
376 nsCSSRuleListSH(nsDOMClassInfoData* aData) : nsArraySH(aData)
377 {
378 }
379
380 virtual ~nsCSSRuleListSH()
381 {
382 }
383
384 virtual nsISupports* GetItemAt(nsISupports *aNative, uint32_t aIndex,
385 nsWrapperCache **aCache, nsresult *aResult) MOZ_OVERRIDE;
386
387 public:
388 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
389 {
390 return new nsCSSRuleListSH(aData);
391 }
392 };
393
394 // WebApps Storage helpers
395
396 class nsStorage2SH : public nsDOMGenericSH
397 {
398 protected:
399 nsStorage2SH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
400 {
401 }
402
403 virtual ~nsStorage2SH()
404 {
405 }
406
407 NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
408 JSObject *obj, jsid id, JSObject **objp,
409 bool *_retval) MOZ_OVERRIDE;
410 NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
411 JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
412 NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
413 JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
414 NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
415 JSObject *obj, jsid id, bool *_retval) MOZ_OVERRIDE;
416 NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
417 JSObject *obj, uint32_t enum_op, JS::Value *statep,
418 jsid *idp, bool *_retval) MOZ_OVERRIDE;
419
420 public:
421 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
422 {
423 return new nsStorage2SH(aData);
424 }
425 };
426
427 // Event handler 'this' translator class, this is called by XPConnect
428 // when a "function interface" (nsIDOMEventListener) is called, this
429 // class extracts 'this' fomr the first argument to the called
430 // function (nsIDOMEventListener::HandleEvent(in nsIDOMEvent)), this
431 // class will pass back nsIDOMEvent::currentTarget to be used as
432 // 'this'.
433
434 class nsEventListenerThisTranslator : public nsIXPCFunctionThisTranslator
435 {
436 public:
437 nsEventListenerThisTranslator()
438 {
439 }
440
441 virtual ~nsEventListenerThisTranslator()
442 {
443 }
444
445 // nsISupports
446 NS_DECL_ISUPPORTS
447
448 // nsIXPCFunctionThisTranslator
449 NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
450 };
451
452 class nsDOMConstructorSH : public nsDOMGenericSH
453 {
454 protected:
455 nsDOMConstructorSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
456 {
457 }
458
459 public:
460 NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
461 JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
462 NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) MOZ_OVERRIDE
463 {
464 return NS_OK;
465 }
466 NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
467 JSObject *obj, jsid id, JSObject **objp,
468 bool *_retval) MOZ_OVERRIDE;
469 NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
470 JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
471
472 NS_IMETHOD Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
473 JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
474
475 NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
476 JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
477 bool *_retval);
478
479 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
480 {
481 return new nsDOMConstructorSH(aData);
482 }
483 };
484
485 class nsNonDOMObjectSH : public nsDOMGenericSH
486 {
487 protected:
488 nsNonDOMObjectSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
489 {
490 }
491
492 virtual ~nsNonDOMObjectSH()
493 {
494 }
495
496 public:
497 NS_IMETHOD GetFlags(uint32_t *aFlags) MOZ_OVERRIDE;
498
499 static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
500 {
501 return new nsNonDOMObjectSH(aData);
502 }
503 };
504
505 #endif /* nsDOMClassInfo_h___ */

mercurial