Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

call native code from javascript

59 views
Skip to first unread message

huazilin

unread,
Aug 30, 2006, 9:43:44 AM8/30/06
to
Hi,
I have developed a native XPCOM component.But when I want to call it

from javascript,I happened some problem . And someone give
the suggestion as following:
1) Implementing nsISecurityCheckedComponent (to allow access to
specific
properties or methods).
2) Implementing nsIClassInfo with the right magic flags (claiming to
be a DOM
class?). This will, for example, allow same-origin access to
properties and
methods unless something else overrides that access level.
3) Installing an accessor (constructor or service accessor?) for your
component
on Window objects. For example, see how XMLHttpRequest used to
work before
it got moved into the core code...

But I can't understand the suggestion,more concretely speaking,I
can't follow even one step.Can someone give me some implement
example.Thanks very much...

Boris Zbarsky

unread,
Aug 30, 2006, 10:40:48 AM8/30/06
to
huazilin wrote:
> 1) Implementing nsISecurityCheckedComponent (to allow access to
> specific
> properties or methods).
> 2) Implementing nsIClassInfo with the right magic flags (claiming to
> be a DOM
> class?). This will, for example, allow same-origin access to

These are mutually exclusive, by the way. So do one or the other.

> But I can't understand the suggestion,more concretely speaking,I
> can't follow even one step.Can someone give me some implement
> example.Thanks very much...

Didn't I say at the time to look at the way XMLHttpRequest works in Gecko
1.8.0.x? See the classinfo stuff in nsXMLHttpRequest.cpp and
nsXMLExtrasModule.cpp there if you want to do classinfo; I believe the category
manager stuff in nsXMLExtrasModule.cpp is what you need to set up constructors.

-Boris

huazilin

unread,
Aug 31, 2006, 4:13:09 AM8/31/06
to

Thank you for your reply!
But I also have some question.
Are there three methods in What your above suggestion or one method
,but need three steps for eventually solve the problem?
Because my poor knowlege about the XPCOM and my poor english,I can't
understand every step clearly. If you have time and have some
implementing examples send to me ,I will appreciate you very very much.
May be you could give me a simple example which is a xpcom component
implementing the security access from javascript,but don't need
authorize the UniversalXpconnect privileges.
If you have some demo,you can send it to my mailbox.
My email is :jingh...@gmail.com
Hoping your reply,thanks .

huazilin

unread,
Aug 31, 2006, 4:13:09 AM8/31/06
to

Thank you for your reply!

Boris Zbarsky

unread,
Sep 1, 2006, 12:00:45 PM9/1/06
to
huazilin wrote:
> Are there three methods in What your above suggestion or one method
> ,but need three steps for eventually solve the problem?

There are two problems that need to be solved:

1) How to get the security manager to allow creation of a JS wrapper for you
C++ object.
2) How to expose a constructor for that object to JS.

To solve #1, you need to either have classinfo or implement
nsISecurityCheckedComponent appropriately.

To solve #2, you want to attach a constructor to the global object.

> If you have time and have some
> implementing examples send to me ,I will appreciate you very very much.

The XMLHttpRequest implementation in Gecko 1.8.0.x _is_ an implementation example.

> May be you could give me a simple example

There isn't one that I know of...

-Boris

Phil McLachlan

unread,
Oct 23, 2006, 4:47:19 PM10/23/06
to
I just found this thread, and Boris' response has been helpful too me,
because I have the same problem. Thanks Boris. It's a work in progress,
but so far I seem to be able to to get past the security checks for JS okay.
I do this by using classinfo and pretending to be a DOM node with the flag
nsIClassInfo::DOM_OBJECT. I followed the XMLHttpRequest to figure out how
to expose a constructor to JS. I was able to do this, but it wasn't easy,
because a lot of the XMLHttpRequest code uses MOZILLA_INTERNAL_API. My
components requires MOZILLA_STRICT_API, because they are both used in a
stand-alone application, and they will be used with a firefox NP plugin. I
can't statically link to things like nsDOMClassInfo or js3250, because they
are different for each release of FF.

However, I've found that it is possible with some trickery to use
XMLHttpRequest as an example to get past the security issue for our own
components. My current problem is that the XPConnect wrapper gets garbage
collected for my custom components, when the custom components are still
alive. At this point, any JS functions that I've added to the wrapper are
destroyed, and a new wrapper is created next time the object is referenced.
According to the description of bug 283129, DOM nodes have their wrappers
preserved, so that properties added from JS are kept.

I'd like to do the same thing for our components, and I've found out that
calling nsIXPCScriptNotify::PreserveWrapper seems to do what I want.
Unfortunately, the current release of FF requires the wrapper to be QI to
nsIDOMNode. Furthermore, this code has changed on head, and the wrapper
must be QI to nsIDOMGCParticipant, instead. I'm not sure my components
should be implementing either of these interfaces, and I'm concerned that it
would be difficult to correctly implementat both or either of them.

Has the code on head stabilized? I don't want to go to the trouble of
getting some great hack to work, if it is going to be broken by changes in
the near future, anyway. I know FF 2.0 is coming out soon, but I'm not sure
whether the new approach (with nsIDOMGCParticipant) will come into effect?
Is there an easy way to tell? Are users of MOZILLA_STRICT_API supposed to
be able to preserve their wrappers and corresponding JS properties? If this
is the case, then what advice can be given on how to do this?

It is tempting to use MOZILLA_INTERNAL_API and create a dependency on
js3250.dll and other internal Mozilla dlls. We have successfully done this
for embedding XPCOM and Mozilla components into our stand-alone application
and our ActiveX control. It would be ironic, if our choice of XPCOM
technology precludes us from creating an NP plugin for Firefox, because we
are forced to use MOZILLA_INTERNAL_API.

Any direction on this issue is much apreciated.

"Boris Zbarsky" <bzba...@mit.edu> wrote in message
news:uc2dndkd9a6hxGXZ...@mozilla.org...

Mitchi

unread,
Nov 10, 2006, 7:01:12 AM11/10/06
to
I'm developing a component and need it to be accessed from a script.

I've seen that you could expose the constructor to JS. Could you
explain me how?
I've been reading the code for the XMLHttpRequest module and i couldn't
figure
it out.

Thanks for your atention.

Phil McLachlan ha escrito:

Boris Zbarsky

unread,
Nov 11, 2006, 12:46:15 AM11/11/06
to
Mitchi wrote:
> I've seen that you could expose the constructor to JS. Could you
> explain me how?
> I've been reading the code for the XMLHttpRequest module and i couldn't
> figure it out.

http://lxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/build/src/nsXMLExtrasModule.cpp#153
is what adds the constructor, basically...

You probably also want something like
http://lxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/build/src/nsXMLExtrasModule.cpp#182
and the classinfo stuff at
http://lxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/build/src/nsXMLExtrasModule.cpp#81
for it to actually be usable, but just that category entry in the "dom class"
category should set up the constructor... Does it not?

-Boris

Mitchi

unread,
Nov 13, 2006, 5:22:05 AM11/13/06
to
Thank you so much, Boris. I was looking on the wrong place.

I'll keep working on this. And sorry for bothering you so frequently.

Boris Zbarsky ha escrito:

Phil McLachlan

unread,
Nov 15, 2006, 6:24:39 PM11/15/06
to
Now that I've been able to do some more thorough testing and clean-up, I
will post the solution I have used to register components for JS, so others
may benefit. This should be easier than looking at the XMLHttpRequest
example, because it is the least amount of things you need to do, and it
will compile with MOZILLA_STRICT_API. I still have not figured out how to
prevent JS attributes from being GC on the XPCOM component yet.

Use the following macro for defining entries in your nsComponentModuleInfo,
in the following way.

#define XPCOM_REGISTER_WITH_JAVASCRIPT( componentName, contractId ) \
static NS_METHOD \
Register##componentName(nsIComponentManager *aCompMgr, \
nsIFile *aPath, \
const char *registryLocation, \
const char *componentType, \
const nsModuleComponentInfo *info) \
{ \
nsCOMPtr< nsIServiceManager > serviceManager; \
nsresult result = NS_GetServiceManager( getter_AddRefs(
serviceManager ) ); \
NS_ENSURE_SUCCESS( result, result ); \
\
nsCOMPtr< nsICategoryManager > catman; \
result = serviceManager->GetServiceByContractID(
"@mozilla.org/categorymanager;1", \
NS_GET_IID(
nsICategoryManager ), \
getter_AddRefs(
catman ) ); \
NS_ENSURE_SUCCESS( result, result ); \
\
nsEmbedCString previous; \
return catman->AddCategoryEntry(JAVASCRIPT_DOM_CLASS, \
#componentName, \
contractId, \
PR_TRUE, PR_TRUE,
getter_Copies(previous)); \
}

XPCOM_REGISTER_WITH_JAVASCRIPT( Foo, FOO_CONTRACTID );

static const nsModuleComponentInfo components[] =
{
{ "Foo",
FOO_CID,
FOO_CONTRACTID,
FooConstructor,
RegisterFoo,
nsnull,
nsnull,
NS_CI_INTERFACE_GETTER_NAME(Foo),
nsnull,
&NS_CLASSINFO_NAME(Foo),
nsIClassInfo::DOM_OBJECT // Pretend to be part of the DOM, so component
has same-origin access.
}
}

In the component, make sure to use the NS_IMPL_ISUPPORTS3_CI family of
macros to declare a class interface.

For each foo, you should initialize before running any JS, with a call to
the following. (One gotcha is that keepAliveFooName must be kept alive as
long as the DOM needs it, so I suggest putting it in a static variable.)

domSOFactory->RegisterDOMClassInfo( keepAliveFooName.get(),
&GetClassInfoFor,
NULL,
interfaces,
DOM_DEFAULT_SCRIPTABLE_FLAGS,
PR_TRUE,
&fooCID );

Where GetClassInfoFor returns the nsIClassInfo object. If you have many
objects to register, then you can use one GetClassInfoFor function that
looks up the proper CID in a map. In any event, a call to the following is
the key part of the module I called GetClassInfoFor. (Another gotcha is
that although GetClassInfoFor may seem like a getter, it is not
XPCOM-compliant, so you should not AddRef, unless you want a memory leak.
This means calling Release on classInfo, after calling GetClassObject and
before returning.)

componentManager->GetClassObject( fooCID,
NS_GET_IID( nsIClassInfo ),
reinterpret_cast< void** >(
&classInfo ) );


Phil McLachlan

unread,
Feb 21, 2007, 5:09:17 PM2/21/07
to
"Phil McLachlan" <pmclachlan@.nospam.vizible.com> wrote in message
news:4vSdnX10sIIrPMbY...@mozilla.org...

> Now that I've been able to do some more thorough testing and clean-up, I
> will post the solution I have used to register components for JS, so
> others may benefit. This should be easier than looking at the
> XMLHttpRequest example, because it is the least amount of things you need
> to do, and it will compile with MOZILLA_STRICT_API. I still have not
> figured out how to prevent JS attributes from being GC on the XPCOM
> component yet.

To answer my own question, I have been able to get expando JS attributes to
work using the approach in Gecko 1.8.1 of nsIDOMGCParticipant
implementation. To do the same, you'll also need a script helper that wraps
an existing DOM helper that you can call to do the PostCreate, AddProperty,
Mark, Finalize, and perhaps NewResolve. I did not bother with the 1.8.0
branch of Gecko.


Luis Fernando

unread,
Feb 22, 2007, 7:58:46 PM2/22/07
to
I am trying to do this, but I can not make it works. I have problems
with the initialization. Can you post here a complete example?

Thanks

Phil McLachlan escribió:

pommyg...@googlemail.com

unread,
Apr 2, 2007, 9:20:10 AM4/2/07
to
>> 1) Implementing nsISecurityCheckedComponent (to allow access to
>> specific
>> properties or methods).
>> 2) Implementing nsIClassInfo with the right magic flags (claiming to
>> be a DOM
>> class?). This will, for example, allow same-origin access to
>
>
>These are mutually exclusive, by the way. So do one or the other.
>
>
>> But I can't understand the suggestion,more concretely speaking,I
>> can't follow even one step.Can someone give me some implement
>> example.Thanks very much...
>
>
>Didn't I say at the time to look at the way XMLHttpRequest works in Gecko
>1.8.0.x? See the classinfo stuff in nsXMLHttpRequest.cpp and
>nsXMLExtrasModule.cpp there if you want to do classinfo; I believe the category
>manager stuff in nsXMLExtrasModule.cpp is what you need to set up constructors.


Er. So if i just have the gecko 1.7.13 sdk (for component developers)
from http://www.mozilla.org/releases/, then
- for the nsISecurityCheckedComponent solution i've got to go get
the seamonkey source too?
- the JavaScript DOM solution needs some mozilla dom stuff also not
found in the sdk?

It is a wee bit strange that just the sdk isn't enough to develop a
public XPCOM component.

0 new messages