|
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___ */ |