1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
|
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* The core XPConnect public interfaces. */
#include "nsISupports.idl"
%{ C++
#include "jspubtd.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
struct JSFreeOp;
class nsWrapperCache;
class nsAXPCNativeCallContext;
%}
/***************************************************************************/
// NB: jsval and jsid are declared in nsrootidl.idl
[ptr] native JSContextPtr(JSContext);
[ptr] native JSClassPtr(JSClass);
[ptr] native JSFreeOpPtr(JSFreeOp);
[ptr] native JSObjectPtr(JSObject);
[ptr] native JSValConstPtr(const JS::Value);
native JSEqualityOp(JSEqualityOp);
[ptr] native JSScriptPtr(JSScript);
[ptr] native voidPtrPtr(void*);
[ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
[ptr] native nsWrapperCachePtr(nsWrapperCache);
[ref] native JSCompartmentOptions(JS::CompartmentOptions);
[ref] native JSCallArgsRef(const JS::CallArgs);
native JSHandleId(JS::Handle<jsid>);
/***************************************************************************/
// forward declarations...
interface nsIXPCScriptable;
interface nsIXPConnect;
interface nsIXPConnectWrappedNative;
interface nsIInterfaceInfo;
interface nsIXPCSecurityManager;
interface nsIPrincipal;
interface nsIClassInfo;
interface nsIVariant;
interface nsIStackFrame;
interface nsIObjectInputStream;
interface nsIObjectOutputStream;
/***************************************************************************/
[uuid(73e6ff4a-ab99-4d99-ac00-ba39ccb8e4d7)]
interface nsIXPConnectJSObjectHolder : nsISupports
{
[notxpcom, nostdcall] JSObjectPtr GetJSObject();
};
[uuid(e787be29-db5d-4a45-a3d6-1de1d6b85c30)]
interface nsIXPConnectWrappedNative : nsIXPConnectJSObjectHolder
{
/* attribute 'JSObject' inherited from nsIXPConnectJSObjectHolder */
readonly attribute nsISupports Native;
readonly attribute JSObjectPtr JSObjectPrototype;
/**
* These are here as an aid to nsIXPCScriptable implementors
*/
nsIInterfaceInfo FindInterfaceWithMember(in JSHandleId nameID);
nsIInterfaceInfo FindInterfaceWithName(in JSHandleId nameID);
[notxpcom] bool HasNativeMember(in JSHandleId name);
void debugDump(in short depth);
/*
* NOTE: Add new IDL methods _before_ the C++ block below if you
* add them. Otherwise the vtable won't be what xpidl thinks it
* is, since GetObjectPrincipal() is virtual.
*/
%{C++
/**
* Faster access to the native object from C++. Will never return null.
*/
nsISupports* Native() const { return mIdentity; }
protected:
nsCOMPtr<nsISupports> mIdentity;
public:
%}
};
%{C++
inline
const nsQueryInterface
do_QueryWrappedNative(nsIXPConnectWrappedNative *aWrappedNative)
{
return nsQueryInterface(aWrappedNative->Native());
}
inline
const nsQueryInterfaceWithError
do_QueryWrappedNative(nsIXPConnectWrappedNative *aWrappedNative,
nsresult *aError)
{
return nsQueryInterfaceWithError(aWrappedNative->Native(), aError);
}
%}
[uuid(3a01b0d6-074b-49ed-bac3-08c76366cae4)]
interface nsIXPConnectWrappedJS : nsIXPConnectJSObjectHolder
{
/* attribute 'JSObject' inherited from nsIXPConnectJSObjectHolder */
readonly attribute nsIInterfaceInfo InterfaceInfo;
readonly attribute nsIIDPtr InterfaceIID;
void debugDump(in short depth);
void aggregatedQueryInterface(in nsIIDRef uuid,
[iid_is(uuid),retval] out nsQIResult result);
};
// Special interface to unmark the internal JSObject.
// QIing to nsIXPConnectWrappedJSUnmarkGray does *not* addref, it only unmarks,
// and QIing to nsIXPConnectWrappedJSUnmarkGray is always supposed to fail.
[builtinclass, uuid(c02a0ce6-275f-4ea1-9c23-08494898b070)]
interface nsIXPConnectWrappedJSUnmarkGray : nsIXPConnectWrappedJS
{
};
/***************************************************************************/
/**
* This is a sort of a placeholder interface. It is not intended to be
* implemented. It exists to give the nsIXPCSecurityManager an iid on
* which to gate a specific activity in XPConnect.
*
* That activity is...
*
* When JavaScript code uses a component that is itself implemented in
* JavaScript then XPConnect will build a wrapper rather than directly
* expose the JSObject of the component. This allows components implemented
* in JavaScript to 'look' just like any other xpcom component (from the
* perspective of the JavaScript caller). This insulates the component from
* the caller and hides any properties or methods that are not part of the
* interface as declared in xpidl. Usually this is a good thing.
*
* However, in some cases it is useful to allow the JS caller access to the
* JS component's underlying implementation. In order to facilitate this
* XPConnect supports the 'wrappedJSObject' property. The caller code can do:
*
* // 'foo' is some xpcom component (that might be implemented in JS).
* try {
* var bar = foo.wrappedJSObject;
* if(bar) {
* // bar is the underlying JSObject. Do stuff with it here.
* }
* } catch(e) {
* // security exception?
* }
*
* Recall that 'foo' above is an XPConnect wrapper, not the underlying JS
* object. The property get "foo.wrappedJSObject" will only succeed if three
* conditions are met:
*
* 1) 'foo' really is an XPConnect wrapper around a JSObject.
* 2) The underlying JSObject actually implements a "wrappedJSObject"
* property that returns a JSObject. This is called by XPConnect. This
* restriction allows wrapped objects to only allow access to the underlying
* JSObject if they choose to do so. Ususally this just means that 'foo'
* would have a property tht looks like:
* this.wrappedJSObject = this.
* 3) The implemementation of nsIXPCSecurityManager (if installed) allows
* a property get on the interface below. Although the JSObject need not
* implement 'nsIXPCWrappedJSObjectGetter', XPConnect will ask the
* security manager if it is OK for the caller to access the only method
* in nsIXPCWrappedJSObjectGetter before allowing the activity. This fits
* in with the security manager paradigm and makes control over accessing
* the property on this interface the control factor for getting the
* underlying wrapped JSObject of a JS component from JS code.
*
* Notes:
*
* a) If 'foo' above were the underlying JSObject and not a wrapper at all,
* then this all just works and XPConnect is not part of the picture at all.
* b) One might ask why 'foo' should not just implement an interface through
* which callers might get at the underlying object. There are three reasons:
* i) XPConnect would still have to do magic since JSObject is not a
* scriptable type.
* ii) JS Components might use aggregation (like C++ objects) and have
* different JSObjects for different interfaces 'within' an aggregate
* object. But, using an additional interface only allows returning one
* underlying JSObject. However, this allows for the possibility that
* each of the aggregte JSObjects could return something different.
* Note that one might do: this.wrappedJSObject = someOtherObject;
* iii) Avoiding the explicit interface makes it easier for both the caller
* and the component.
*
* Anyway, some future implementation of nsIXPCSecurityManager might want
* do special processing on 'nsIXPCSecurityManager::CanGetProperty' when
* the interface id is that of nsIXPCWrappedJSObjectGetter.
*/
[scriptable, uuid(254bb2e0-6439-11d4-8fe0-0010a4e73d9a)]
interface nsIXPCWrappedJSObjectGetter : nsISupports
{
readonly attribute nsISupports neverCalled;
};
/***************************************************************************/
/*
* This interface is implemented by outside code and registered with xpconnect
* via nsIXPConnect::setFunctionThisTranslator.
*
* The reason this exists is to support calls to JavaScript event callbacks
* needed by the DOM via xpconnect from C++ code.
*
* We've added support for wrapping JS function objects as xpcom interfaces
* by declaring the given interface as a [function] interface. However, to
* support the requirements of JS event callbacks we need to call the JS
* function with the 'this' set as the JSObject for which the event is being
* fired; e.g. a form node.
*
* We've decided that for all cases we care about the appropriate 'this' object
* can be derived from the first param in the call to the callback. In the
* event handler case the first param is an event object.
*
* Though we can't change all the JS code so that it would setup its own 'this',
* we can add plugin 'helper' support to xpconnect. And that is what we have
* here.
*
* The idea is that at startup time some code that cares about this issue
* (e.g. the DOM helper code) can register a nsIXPCFunctionThisTranslator
* object with xpconnect to handle calls to [function] interfaces of a given
* iid. When xpconnect goes to invoke a method on a wrapped JSObject for
* an interface marked as [function], xpconnect will check if the first param
* of the method is an xpcom object pointer and if so it will check to see if a
* nsIXPCFunctionThisTranslator has been registered for the given iid of the
* interface being called. If so it will call the translator and get an
* interface pointer to use as the 'this' for the call. If the translator
* returns a non-null interface pointer (which it should then have addref'd
* since it is being returned as an out param), xpconnect will attempt to build
* a wrapper around the pointer and get a JSObject from that wrapper to use
* as the 'this' for the call.
*
* If a null interface pointer is returned then xpconnect will use the default
* 'this' - the same JSObject as the function object it is calling.
*/
[uuid(f5f84b70-92eb-41f1-a1dd-2eaac0ed564c)]
interface nsIXPCFunctionThisTranslator : nsISupports
{
nsISupports TranslateThis(in nsISupports aInitialThis);
};
/***************************************************************************/
%{ C++
// For use with the service manager
// {CB6593E0-F9B2-11d2-BDD6-000064657374}
#define NS_XPCONNECT_CID \
{ 0xcb6593e0, 0xf9b2, 0x11d2, \
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[noscript, uuid(768507b5-b981-40c7-8276-f6a1da502a24)]
interface nsIXPConnect : nsISupports
{
%{ C++
NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCONNECT_CID)
%}
/**
* Creates a new global object using the given aCOMObj as the global
* object. The object will be set up according to the flags (defined
* below). If you do not pass INIT_JS_STANDARD_CLASSES, then aCOMObj
* must implement nsIXPCScriptable so it can resolve the standard
* classes when asked by the JS engine.
*
* @param aJSContext the context to use while creating the global object.
* @param aCOMObj the native object that represents the global object.
* @param aPrincipal the principal of the code that will run in this
* compartment. Can be null if not on the main thread.
* @param aFlags one of the flags below specifying what options this
* global object wants.
* @param aOptions JSAPI-specific options for the new compartment.
*/
nsIXPConnectJSObjectHolder
initClassesWithNewWrappedGlobal(
in JSContextPtr aJSContext,
in nsISupports aCOMObj,
in nsIPrincipal aPrincipal,
in uint32_t aFlags,
in JSCompartmentOptions aOptions);
const uint32_t INIT_JS_STANDARD_CLASSES = 1 << 0;
const uint32_t DONT_FIRE_ONNEWGLOBALHOOK = 1 << 1;
const uint32_t OMIT_COMPONENTS_OBJECT = 1 << 2;
/**
* wrapNative will create a new JSObject or return an existing one.
*
* This method now correctly deals with cases where the passed in xpcom
* object already has an associated JSObject for the cases:
* 1) The xpcom object has already been wrapped for use in the same scope
* as an nsIXPConnectWrappedNative.
* 2) The xpcom object is in fact a nsIXPConnectWrappedJS and thus already
* has an underlying JSObject.
*
* It *might* be possible to QueryInterface the nsIXPConnectJSObjectHolder
* returned by the method into a nsIXPConnectWrappedNative or a
* nsIXPConnectWrappedJS.
*
* This method will never wrap the JSObject involved in an
* XPCNativeWrapper before returning.
*
* Returns:
* success:
* NS_OK
* failure:
* NS_ERROR_XPC_BAD_CONVERT_NATIVE
* NS_ERROR_XPC_CANT_GET_JSOBJECT_OF_DOM_OBJECT
* NS_ERROR_FAILURE
*/
JSObjectPtr
wrapNative(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsISupports aCOMObj,
in nsIIDRef aIID);
/**
* Same as wrapNative, but it returns the JSObject in an nsIXPConnectJSObjectHolder.
*/
nsIXPConnectJSObjectHolder
wrapNativeHolder(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsISupports aCOMObj,
in nsIIDRef aIID);
/**
* Same as wrapNative, but it returns the JSObject in aVal. C++ callers
* must ensure that aVal is rooted.
* aIID may be null, it means the same as passing in
* &NS_GET_IID(nsISupports) but when passing in null certain shortcuts
* can be taken because we know without comparing IIDs that the caller is
* asking for an nsISupports wrapper.
* If aAllowWrapper, then the returned value will be wrapped in the proper
* type of security wrapper on top of the XPCWrappedNative (if needed).
* This method doesn't push aJSContext on the context stack, so the caller
* is required to push it if the top of the context stack is not equal to
* aJSContext.
*/
void
wrapNativeToJSVal(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsISupports aCOMObj,
in nsWrapperCachePtr aCache,
in nsIIDPtr aIID,
in boolean aAllowWrapper,
out jsval aVal);
/**
* wrapJS will yield a new or previously existing xpcom interface pointer
* to represent the JSObject passed in.
*
* This method now correctly deals with cases where the passed in JSObject
* already has an associated xpcom interface for the cases:
* 1) The JSObject has already been wrapped as a nsIXPConnectWrappedJS.
* 2) The JSObject is in fact a nsIXPConnectWrappedNative and thus already
* has an underlying xpcom object.
* 3) The JSObject is of a jsclass which supports getting the nsISupports
* from the JSObject directly. This is used for idlc style objects
* (e.g. DOM objects).
*
* It *might* be possible to QueryInterface the resulting interface pointer
* to nsIXPConnectWrappedJS.
*
* Returns:
* success:
* NS_OK
* failure:
* NS_ERROR_XPC_BAD_CONVERT_JS
* NS_ERROR_FAILURE
*/
void
wrapJS(in JSContextPtr aJSContext,
in JSObjectPtr aJSObj,
in nsIIDRef aIID,
[iid_is(aIID),retval] out nsQIResult result);
/**
* Wraps the given jsval in a nsIVariant and returns the new variant.
*/
nsIVariant
jSValToVariant(in JSContextPtr cx, in jsval aJSVal);
/**
* This only succeeds if the JSObject is a nsIXPConnectWrappedNative.
* A new wrapper is *never* constructed.
*/
nsIXPConnectWrappedNative
getWrappedNativeOfJSObject(in JSContextPtr aJSContext,
in JSObjectPtr aJSObj);
// Will return null if there is no JS stack right now.
readonly attribute nsIStackFrame CurrentJSStack;
readonly attribute nsAXPCNativeCallContextPtr CurrentNativeCallContext;
void debugDump(in short depth);
void debugDumpObject(in nsISupports aCOMObj, in short depth);
void debugDumpJSStack(in boolean showArgs,
in boolean showLocals,
in boolean showThisProps);
/**
* wrapJSAggregatedToNative is just like wrapJS except it is used in cases
* where the JSObject is also aggregated to some native xpcom Object.
* At present XBL is the only system that might want to do this.
*
* XXX write more!
*
* Returns:
* success:
* NS_OK
* failure:
* NS_ERROR_XPC_BAD_CONVERT_JS
* NS_ERROR_FAILURE
*/
void
wrapJSAggregatedToNative(in nsISupports aOuter,
in JSContextPtr aJSContext,
in JSObjectPtr aJSObj,
in nsIIDRef aIID,
[iid_is(aIID),retval] out nsQIResult result);
// Methods added since mozilla 0.6....
/**
* This only succeeds if the native object is already wrapped by xpconnect.
* A new wrapper is *never* constructed.
*/
nsIXPConnectWrappedNative
getWrappedNativeOfNativeObject(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsISupports aCOMObj,
in nsIIDRef aIID);
void
setFunctionThisTranslator(in nsIIDRef aIID,
in nsIXPCFunctionThisTranslator aTranslator);
JSObjectPtr
getWrappedNativePrototype(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsIClassInfo aClassInfo);
jsval variantToJS(in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value);
nsIVariant JSToVariant(in JSContextPtr ctx, in jsval value);
/**
* Create a sandbox for evaluating code in isolation using
* evalInSandboxObject().
*
* @param cx A context to use when creating the sandbox object.
* @param principal The principal (or NULL to use the null principal)
* to use when evaluating code in this sandbox.
*/
[noscript] JSObjectPtr createSandbox(in JSContextPtr cx, in nsIPrincipal principal);
/**
* Evaluate script in a sandbox, completely isolated from all
* other running scripts.
*
* @param source The source of the script to evaluate.
* @param filename The filename of the script. May be null.
* @param cx The context to use when setting up the evaluation of
* the script. The actual evaluation will happen on a new
* temporary context.
* @param sandbox The sandbox object to evaluate the script in.
* @param version The JavaScript version to use for evaluating the script.
* Should be a valid JSVersion from jspubtd.h.
* @return The result of the evaluation as a jsval. If the caller
* intends to use the return value from this call the caller
* is responsible for rooting the jsval before making a call
* to this method.
*/
[noscript] jsval evalInSandboxObject(in AString source, in string filename,
in JSContextPtr cx,
in JSObjectPtr sandbox,
in int32_t version);
/**
* Trigger a JS garbage collection.
* Use a js::gcreason::Reason from jsfriendapi.h for the kind.
*/
void GarbageCollect(in uint32_t reason);
/**
* Signals a good place to do an incremental GC slice, because the
* browser is drawing a frame.
*/
void NotifyDidPaint();
%{C++
/**
* Get the object principal for this wrapper. Note that this may well end
* up being null; in that case one should seek principals elsewhere. Null
* here does NOT indicate system principal or no principals at all, just
* that this wrapper doesn't have an intrinsic one.
*/
virtual nsIPrincipal* GetPrincipal(JSObject* obj,
bool allowShortCircuit) const = 0;
virtual char* DebugPrintJSStack(bool showArgs,
bool showLocals,
bool showThisProps) = 0;
%}
[noscript] void writeScript(in nsIObjectOutputStream aStream,
in JSContextPtr aJSContext,
in JSScriptPtr aJSScript);
[noscript] JSScriptPtr readScript(in nsIObjectInputStream aStream,
in JSContextPtr aJSContext);
[noscript] void writeFunction(in nsIObjectOutputStream aStream,
in JSContextPtr aJSContext,
in JSObjectPtr aJSObject);
[noscript] JSObjectPtr readFunction(in nsIObjectInputStream aStream,
in JSContextPtr aJSContext);
};
|