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

Extending javascript

11 views
Skip to first unread message

Mitchi

unread,
Oct 24, 2006, 8:59:17 AM10/24/06
to
Hi.

We're developing a CSP that works within a Flash Memory Stick with USB
interface with its own OS that offer services through sockets.

We've got a pkcs11 that works on firefox, and we wanted to develop a
XPCOM component to provide a set of javascript functions to interact
with the CSP device, in order to access certain services from a script
(signing, getting the device id, etc.)

I was reading a lot of documentation and made some tests and
implemented a trivuial component and some scripts to test how did it
work.

I found that, to call the functions defined on the component in the
client, the script needs to obtain extended privileges, and the only
way to gain them is using a signed script or enabling codebase
principals. Enabling codebase principals in the client isn't a good
idea, son the only way is to use signed scripts.

The problem comes with the new model applied up from Communicator 4.
Everything (html page, scripts and signature files) has to be inside a
JAR package. This makes impossible to invoke scripts using standard
URLs (you need to use that of jar:http:...!file.jar/page.html), making
it horrible to create dynamic web pages.

Am I right?, I mean, Is this the only way to extend the javascript
functionality in firefox?

About the privileges. UniversalXPConnect is the only privilege I can
have? Are there any other more restricted privileges?

About the model used formerly (script signature referenced by an
attribute on the script tag), ¿Isn't it anymore supported? And, I
hope i'm not rude asking this, ¿Which was the cause to decide changing
it?

I'd thank any suggestion you may give me to help finishing this project
propperly, and correcting me if there's any other way to use xpcom
functions from a script.

Thank you very much for your attention.

PS: I'd like to suggest something. It's only my point of view, and I
know it may be difficult to bring up this, but I just want to give some
ideas that may be good or may suggest better ones.

The security problem is that, if you gain UniversalXPConnect
privileges, you can both access your component or any other critical
components that come with firefox. I think that the solution comes by
defining different security levels to access the components. Now there
are only scriptable or not scriptable components, but scriptable
components should be classified within 2 or 3 levels, letting a level
for non critical components. (All in all, users always install
extensions or things like that without knowing what it really does) And
each level should accept scripts with different levels of trust (top
level JAR method, middle level pre-JAR Method, and lower level no
signing). Suggest things around this. Thank you.

timeless

unread,
Nov 4, 2006, 7:55:35 PM11/4/06
to
Look at how window.sidebar and window.XMLHttpRequest and friends work.
You don't need to require things to be signed. However creating such a
thing does mean it's your responsibility to not enable web pages to
harm the users.

Mitchi

unread,
Nov 6, 2006, 3:15:56 AM11/6/06
to

timeless ha escrito:

> Look at how window.sidebar and window.XMLHttpRequest and friends work.
> You don't need to require things to be signed.

Sure, but these are part of the DOM, and accessing them is not so
critical.

The problem is that XPCOM is a very powerful way to let developers
extend mozilla's functionality, but the strictness of the access method
makes it completely unusable.

> However creating such a
> thing does mean it's your responsibility to not enable web pages to
> harm the users.

I don't agree. My responsability is to create a component that offers
some functionality and take care it has no security holes that let
somebody use it in an unexpected way. The user makes the decission to
install a component and to trust the developer and trust that it
provides the services he has been told, so I think that the usage of it
should be trusted just by letting its instalation (signing the
component, not the scripts), the same way is done with the extensions.
I mean, You can install an unsigned firefox extension (most of them are
unsigned), and they could be as harmless as my component (The only
difference is that the extension is activated by an event, but it's
really easy to make it react to a structure on the document loaded).
¿Why the extension can work freely and my component has to be accessed
by signed scripts and static html docs packed in a jar?

The answer is that, installing an extension provides just this
functionality, but giving universalXPConnect access lets you use every
scriptable component, even the critical ones.

So, I belive that the access model should be different, letting you
gain access to just a component, not to every one.

Boris Zbarsky

unread,
Nov 6, 2006, 10:55:15 AM11/6/06
to
Mitchi wrote:
>> Look at how window.sidebar and window.XMLHttpRequest and friends work.
>> You don't need to require things to be signed.
>
> Sure, but these are part of the DOM, and accessing them is not so
> critical.

You missed timeless' point. His point was that your component can attach hooks
to the global JS object allowing untrusted content to call into your component
and only your component. That's what XMLHttpRequest does.

> The problem is that XPCOM is a very powerful way to let developers
> extend mozilla's functionality, but the strictness of the access method
> makes it completely unusable.

It's not really designed for use from web pages, yeah.

> should be trusted just by letting its instalation (signing the
> component, not the scripts), the same way is done with the extensions.

Sure.

> I mean, You can install an unsigned firefox extension (most of them are
> unsigned), and they could be as harmless as my component (The only
> difference is that the extension is activated by an event, but it's
> really easy to make it react to a structure on the document loaded).
> ¿Why the extension can work freely and my component has to be accessed
> by signed scripts and static html docs packed in a jar?

In part, because the extension is reacting when _it_ wants to react, whereas you
want a scenario where the component reacts when the _page_ wants it to react.
So there's a major difference in control flow.

> The answer is that, installing an extension provides just this
> functionality

Not strictly true...

> but giving universalXPConnect access lets you use every
> scriptable component, even the critical ones.

Right.

> So, I belive that the access model should be different, letting you
> gain access to just a component, not to every one.

Care to write up a proposal for how this should work, exactly? That is, how
does one know which scripts should be allowed to instantiate which components?
Or are you saying that components should have an easy way to say "allow me to be
instantiated by all scripts"?

-Boris

Mitchi

unread,
Nov 8, 2006, 5:31:19 AM11/8/06
to

Thanks for your answer.

Boris Zbarsky ha escrito:

> Mitchi wrote:
> >> Look at how window.sidebar and window.XMLHttpRequest and friends work.
> >> You don't need to require things to be signed.
> >
> > Sure, but these are part of the DOM, and accessing them is not so
> > critical.
>
> You missed timeless' point. His point was that your component can attach hooks
> to the global JS object allowing untrusted content to call into your component
> and only your component. That's what XMLHttpRequest does.
>

I don't catch what you're trying to tell, I'm sorry. Could you explain
it more?

> > The problem is that XPCOM is a very powerful way to let developers
> > extend mozilla's functionality, but the strictness of the access method
> > makes it completely unusable.
>
> It's not really designed for use from web pages, yeah.
>

Ok, so there never will be a way to extend the javascript
functionality, right?

> > should be trusted just by letting its instalation (signing the
> > component, not the scripts), the same way is done with the extensions.
>
> Sure.
>
> > I mean, You can install an unsigned firefox extension (most of them are
> > unsigned), and they could be as harmless as my component (The only
> > difference is that the extension is activated by an event, but it's
> > really easy to make it react to a structure on the document loaded).
> > ¿Why the extension can work freely and my component has to be accessed
> > by signed scripts and static html docs packed in a jar?
>
> In part, because the extension is reacting when _it_ wants to react, whereas you
> want a scenario where the component reacts when the _page_ wants it to react.
> So there's a major difference in control flow.
>

Yeah, but if my component offers a well defined set of services, i make
the component react the way it wants, and you can make a extension that
reacts when the page wants. I know it's not the same, but it
approaches.


> > The answer is that, installing an extension provides just this
> > functionality
>
> Not strictly true...
>
> > but giving universalXPConnect access lets you use every
> > scriptable component, even the critical ones.
>
> Right.
>
> > So, I belive that the access model should be different, letting you
> > gain access to just a component, not to every one.
>
> Care to write up a proposal for how this should work, exactly?

Ok, I knew from the beginning that this wasn't an easy thing. Even
more, I really think it can't be done without starting from the
beggining with a new model, so it's stupid to think about doing it, but
I was just giving my opinion. Now I don't care about this, cause we
have used an applet to solve the problem. It's just discussing for fun.

This is another point, the applets. By default, all the policies are
active, so if the user trusts the applet, it has full access. You can
restrict quite well the policies, but it can only be done from the
config file, manually, so I'm afraid that 99.99% of users around the
world have very permisive policies in their Java VM. Why the security
here is so relaxed?

> That is, how does one know which scripts should be allowed to instantiate which components?
> Or are you saying that components should have an easy way to say "allow me to be
> instantiated by all scripts"?

Just like the ActiveX model. The problem with XPConnect is that you
gain access to everything or you gain access to nothing, but not just
what you want. And if you gain access you can only work with static web
pages.

This is a question I'd appreciate you could solve. In signed scripts,
even the html page has to be signed and got into the jar file. ¿Why?.
Which was the porblem with the model used till communicator 4 (having
an 'archive' attribute in the script tag to refer the signature file
for the script)? I think it's because you also want to certify the use
it's done given to the script, but isn't that a huge level of paranoia?


Understand me. We could be discussing this for a hundred years and
nobody would have the point. It's only a point of view matter. I'm
just a bit frustrated because this would have been an elegant sollution
to our problem and it couldn't be.

Of course, my opinion about mozilla software is still as good as before
I started working on this.


Thanks for your attention.

Boris Zbarsky

unread,
Nov 8, 2006, 10:34:40 AM11/8/06
to
Mitchi wrote:
>> You missed timeless' point. His point was that your component can attach hooks
>> to the global JS object allowing untrusted content to call into your component
>> and only your component. That's what XMLHttpRequest does.
>
> I don't catch what you're trying to tell, I'm sorry. Could you explain
> it more?

var http = new XMLHttpRequest();

When you do that, a constructor function is called. This constructor function
is attached to the global object by the XMLHttpRequest component. This allows
construction of an XMLHttpRequest object without needing access to
Components.classes or knowing its contract id.

Same this for DOMParser, DOMSerializer.

>>> The problem is that XPCOM is a very powerful way to let developers
>>> extend mozilla's functionality, but the strictness of the access method
>>> makes it completely unusable.
>> It's not really designed for use from web pages, yeah.
>
> Ok, so there never will be a way to extend the javascript
> functionality, right?

All I said is that right now you have to extend by attaching
constructors/getters to the global object instead of just allowing web pages to
instantiate you by contract.

-Boris

Mitchi

unread,
Nov 9, 2006, 6:00:25 AM11/9/06
to

Boris Zbarsky ha escrito:

> Mitchi wrote:
> >> You missed timeless' point. His point was that your component can attach hooks
> >> to the global JS object allowing untrusted content to call into your component
> >> and only your component. That's what XMLHttpRequest does.
> >
> > I don't catch what you're trying to tell, I'm sorry. Could you explain
> > it more?
>
> var http = new XMLHttpRequest();
>
> When you do that, a constructor function is called. This constructor function
> is attached to the global object by the XMLHttpRequest component. This allows
> construction of an XMLHttpRequest object without needing access to
> Components.classes or knowing its contract id.
>
> Same this for DOMParser, DOMSerializer.
>

Ok. I get it.


> >>> The problem is that XPCOM is a very powerful way to let developers
> >>> extend mozilla's functionality, but the strictness of the access method
> >>> makes it completely unusable.
> >> It's not really designed for use from web pages, yeah.
> >
> > Ok, so there never will be a way to extend the javascript
> > functionality, right?
>
> All I said is that right now you have to extend by attaching
> constructors/getters to the global object instead of just allowing web pages to
> instantiate you by contract.
>

Oh! Thank The Holy Flying Spaghetti Monster!!!!

So there's a way to access my component from javascript without needing
a signed script?

Oh, fuck! I feel completely stupid now, man! Now that we have used a
different and less elegant solution... this is not documented in
mozilla developers, right?

My boss has just told me to follow this thread and try to solve the
problem with a component. I've been looking for info and I just found
another message where you recommended to see how it's done with the
code of XMLHttpRequest in the files nsXMLExtrasModule.cpp and
nsXMLHttpRequest.cpp. There isn't anymore documentation, right? If you
could give me some more information about this, please, do it.

Finally I really must thank you for your help. I felt completely
frustrated with the idea that there wasn't a solution, and you have
opened a new door to keep on working. I am truly sorry if you were
annoyed for my previous messages and the ignorance I showed there.

Thank you.


> -Boris

Boris Zbarsky

unread,
Nov 9, 2006, 11:25:22 AM11/9/06
to
Mitchi wrote:
> Oh, fuck! I feel completely stupid now, man! Now that we have used a
> different and less elegant solution... this is not documented in
> mozilla developers, right?

Hmm.... I don't think it is. :( Certainly no hits on JAVASCRIPT_DOM_CLASS or
"JavaScript DOM class".

I hate to ask this, but would you possibly be willing to keep track of the steps
you need to take to do this? Once that's written down somewhere we can throw it
up on the wiki and it'll at least be _something_.

> If you could give me some more information about this, please, do it.

I think the only other useful information is that if you're using XMLHttpRequest
as a model, make sure to look at the 1.8.0 branch code. On the 1.8 branch and
on trunk that code got moved into core content, so doesn't use the "external DOM
class" setup anymore...

Oh, and no need to apologize. This stuff is incredibly confusing at first
sight..... and second, third, etc. sight too. :(

-Boris

Mitchi

unread,
Nov 10, 2006, 3:13:16 AM11/10/06
to
> I hate to ask this, but would you possibly be willing to keep track of the steps
> you need to take to do this? Once that's written down somewhere we can throw it
> up on the wiki and it'll at least be _something_.


Sure. As soon as i can solve the problem (I hope I'll solve it), i'll
write down a step by step tutorial.

timeless

unread,
Nov 27, 2006, 2:55:07 AM11/27/06
to
Mitchi wrote:
> Sure. As soon as i can solve the problem (I hope I'll solve it), i'll
> write down a step by step tutorial.

We're still waiting for your tutorial. But seriously, it shouldn't be
too hard to just document the implementation of window.sidebar.

(not that window.sidebar is good code or anything, because it isn't.)

Mitchi

unread,
Nov 27, 2006, 4:26:59 AM11/27/06
to
I had to leave this for some time, and then I had to consider
implementing this with a plugin (an order from above), but I decided
the plugin way was more confusing (please, correct me if I'm wrong).
Now I'm back on it.

I was working over the XMLHttpRequest because it's implemented in C++,
but there is some code I don't understand and I was trying to guess.
The only thing that worries me is what is told in this thread
http://groups.google.es/group/mozilla.dev.tech.xpcom/browse_thread/thread/1d914272653ee02b/ff5d7649b60fad21?lnk=raot#ff5d7649b60fad21

about the XPConnect doing garbage collection while the object is still
alive. I need to be sure it will work when I do all the hard work
creating component.


> But seriously, it shouldn't be
> too hard to just document the implementation of window.sidebar.

sure, it takes just two minutes to realize that the code from this
line:

http://lxr.mozilla.org/mozilla1.8.0/source/xpfe/components/sidebar/src/nsSidebar.js#306

until line 394 is what you need to register your component as a
javascript dom object . I also understand, in general, what is being
done there (The component implements the classInfo interface and shows
itself as a DOM object to the component manager), but i was trying to
understand it line to line. But my problem is with the C++ version,
where things aren't as clear as in the sidebar implementation.


timeless ha escrito:

> Mitchi wrote:
> > Sure. As soon as i can solve the problem (I hope I'll solve it), i'll
> > write down a step by step tutorial.
>
> We're still waiting for your tutorial.
>

timeless

unread,
Nov 27, 2006, 12:16:40 PM11/27/06
to
Mitchi wrote:
> i was trying to understand it line to line.

> But my problem is with the C++ version,
> where things aren't as clear as in the sidebar implementation.

your problem is trying to use the C++ version instead of finding the
one to one mapping between JS and C++.

Not every line in here is annotated, but almost all of them are obvious
one to one mappings. Note that many lines in JS or C++ need an
additional line in the other language. I might note that in some cases,
in others, well.... if the line counts don't match, assume that one of
them expanded :).

it goes something like this:

/* IDL file myIFoopy.idl */
[scriptable]
interface myIFoopy : nsISupports {
/* method
* @param foopy something to think about
*
* @return a randomish number based on howtever the implementation
feels about foopy
*/
long method(in AString foopy);
/* dohtem
* @param out ypoof something to get
* @bugs this should just be long dohtem() but that wouldn't demo
outs in js.
* as such, using this method in js is a royal pain
*/
void dohtem(out long ypoof);
/* cupid is not readonly, it has both a setter and a getter.
* it stores a cupid.
* how cupid is used is entirely implementation specific.
*/
attribute nsISupports cupid;
attribute nsISupports dipuc;
}


/* JS impl myFoopy.js */
function myFoopy(){}
myFoopy.prototype = {
/* this is the dirty definition approach, objects normally like to
know who their
* constructor is, but we're destroying the object here, so it
doesn't unless we
* store it by hand.
*
* this is xpcom private
*/
constructor: myFoopy,
/*
* this is xpcom public if you QI to nsISupports (and everything
derives from
* nsISupports, so you don't actually need to QI to it unless you
have a tearoff
* which you could have in c++ [js is protected from that problem by
xpconnect
* magic].
*/
QueryInterface: function
/* what matters to xpcom is the public name before the colon.
* the name of the function is an internal name used by things like
debuggers
* and profilers, and people who want to read and understand your
code.
*/
myFoopy_QueryInterface(iid) {
/* I refuse to use sugar: for each (i in this.interfaces)
* here because when someone pollutes Object.prototype or
Array.prototype,
* the sugar breaks and people wonder why things stopped working.
* this happens often enough that the sugar is just dangerous.
* plus that sugar can't be converted to C++, and it is possible to
write this sugar free
* version in C++, although it isn't recommended.
*/
for (var i = 0; i < this.interfaces; ++i) {
if (iid.equals(this.interfaces[i]))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
},
/* this is as close to table driven qi as js can get, and it's
conveniently a first step
* to nsIClassInfo.
*
* this is xpcom private
*/
interfaces: [
Components.interfaces.nsISupports,
Components.interfaces.myIFoopy
],
/* storage for cupid
*
* this is xpcom private
*/
_cupid: null,
/* myIFoopy.method
* note that the case for method here matches the case in the idl
file.
*
* this is xpcom public if you QI to myIFoopy
*/
method: function myFoopy_method(foopy) {
if (foopy.charAt(0) == "f" &&
foopy.charAt(1) == "o" &&
!foopy.charAt(2))
return 10;
if (foopy == 'of') {
/* it sucks, but this is how you get the result of an out value
for an xpcom method.
* this is also why this.dohtem should be a long dohtem();
* instead of void dohtem(out long ypoof);
*
* first you need an object
*/
var ypoof = {};
/* then you pass it to the C++; this feels so much like visual
basic.... */
this.dohtem(ypoof);
/* then you grab the magically populated value from the object,
* that's your out-ed value.
*/
return ypoof.value;
}
return 19;
},
/* myIFoopy.dohtem
* note that the case for method here matches the case in the idl
file.
*
* this is xpcom public if you QI to myIFoopy
*/
dohtem: function myFoopy_dohtem(foopy) {
foopy.value = 15;
},
/* getter myIFoopy.cupid
* this is written using syntactic sugar
* this is xpcom public if you QI to myIFoopy
*/
get cupid() {
return this._cupid;
},
/* setter myIFoopy.cupid
* this is written using syntactic sugar
* this is xpcom public if you QI to myIFoopy
*/
set cupid(cupid) {
this._cupid = cupid;
/* this is only in case someone calls our setter from js and it
only makes sense */
},
/* getter myIFoopy.dipuc
* this is not written using syntactic sugar
* this is xpcom public if you QI to myIFoopy
*/
getDipuc() {
return this.cupid;
},
/* setter myIFoopy.dipuc
* this is not written using syntactic sugar
* this is xpcom public if you QI to myIFoopy
*/
setDipuc: function myFoopy_SetDipuc (cupid) {
/* the use of this. is here is required for js,
* and can be conveniently seen as related to the C++
* example if you pretend that this is an xpcom pointer instead of
a native pointer
*/
return this.cupid = cupid;
}
}

/* the implementation of nsIModule is already documented elsewhere and
is beyond the scope of this mapping */

/* C++ impl myFoopy.cpp */

class myFoopy : public myIFoopy {
private:
/* constructor
*
* this is xpcom private
*/
myFoopy();
/* storage for cupid
*
* this is xpcom private
*/
nsCOMPtr<nsISupports> mCupid;
public:
NS_DECL_MYIFOOPY;
NS_DECL_ISUPPORTS;
}
myFoopy::myFoopy(){}

/* note that you can only have one of these per class since they define
the same methods
/* this is the standard syntatic sugar approach */
NS_IMPL_ISUPPORTS1(myFoopy, myIFoopy)
/* end standard sugar */

/* this is a more flexible slightly sugary approach */
NS_IMPL_ADDREF(myFoopy)
NS_IMPL_RELEASE(myFoopy)
NS_INTERFACE_MAP_BEGIN(myFoopy)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIFoopy)
NS_INTERFACE_MAP_END(myFoopy)
/* end rarer alternate sugary approach */

/*
* this is xpcom public if you QI to myIFoopy
*/
NS_IMETHODIMP
/* myIFoopy.method
* note the lack of any special prefix but that method is
InitialCaps,
* unlike the idl declaration.
*/
myFoopy::Method(/*in strings are a bit special*/ const nsAString
&foopy, PRInt32 *aRetval) {
if (foopy.CharAt(0) == "f" &&
foopy.CharAt(1) == "o" &&
foopy.CharAt(2) == "") {
/* note that it takes two lines to express a return */
*aRetval = 10;
return NS_OK;
}
/* but this allows us to not use 'else', just as the js doesn't
need it ... */
if (foopy.EqualsLiteral("of")) {
/* sometimes C++ is shorter ... */
Dohtem(aRetval);
return NS_OK;
}
*aRetval = 19;
return NS_OK;
}
NS_IMETHODIMP
/* myIFoopy.dohtem
* note the lack of any special prefix but that method is
InitialCaps,
* unlike the idl declaration.
*/
myFoopy::Dohtem(PRInt32 *aYpoof) {
*aYpoof = 15;
return NS_OK;
}
/*
* this is xpcom public if you QI to myIFoopy
*/
NS_IMETHODIMP
/* getter myIFoopy.cupid
* note that Get is part of the name and both Get and Cupid are
InitialCaps
* note the double pointer since we need to be able to pass out a
pointer
*/
myFoopy::GetCupid(nsISupports **aResult) {
/* xpcom says we addref for getters... */
NS_IF_ADDREF(*aResult = mCupid);
return NS_OK;
}
/*
* this is xpcom public if you QI to myIFoopy
*/
NS_IMETHODIMP
/* setter myIFoopy.cupid
* note that Set is part of the name and both Set and Cupid are
InitialCaps
* note the single pointer since we only need to be given a pointer
*/
myFoopy::SetCupid(nsISupports *aCupid) {
mCupid = aCupid;
}
/*
* this is xpcom public if you QI to myIFoopy
*/
NS_IMETHODIMP
/* getter myIFoopy.dipuc
* note that Get is part of the name and both Get and Dipuc are
InitialCaps
* note the double pointer since we need to be able to pass out a
pointer
*/
myFoopy::GetDipuc(nsISupports **aResult) {
/* xpcom says we addref for getters... */
/* but the code we're calling does that, so we just let it manage
the reference
* since we aren't dropping it or holding it or otherwise
influencing the one it
* returns.
*/
return GetCupid(aResult);
}
/*
* this is xpcom public if you QI to myIFoopy
*/
NS_IMETHODIMP
/* setter myIFoopy.dipuc
* note that Set is part of the name and both Set and Dipuc are
InitialCaps
* note the single pointer since we only need to be given a pointer
*/
myFoopy::SetDipuc(nsISupports *aCupid) {
/* the useless use of this-> is here for equivalence
* to the use of this. in js,
* and can be conveniently seen as related to the JS
* example if you pretend that this is an xpcom pointer to myIFoopy
* instead of a pointer to myFoopy.
*/
* to the useless use of this. in the js example */
return this->SetCupid(aCupid);
}


/* the implementation of nsIModule is already documented elsewhere and
is beyond the scope of this mapping */

/* XPCOM Exception handling (JavaScript) eh.js: */
function eh_js() {
try {
xpcom_wrapped_object.method();
} catch (e) {
switch (e.result) {
case Components.results.NS_ERROR_FILE_UNRECOGNIZED_PATH:
doSomething();
return;
case Components.results.NS_ERROR_FILE_UNRESOLVABLE_SYMLINK:
throw Components.results.NS_ERROR_FILE_EXECUTION_FAILED;
case Components.results.NS_ERROR_FILE_UNKNOWN_TYPE:
throw e.result;
default:
doSomethingElse();
return;
}
}
}

/* XPCOM Exception handling (C++) eh.cpp: */
nsresult Eh_js() {
/* this is equivalent to e.result */
nsresult rv;
/* this is the method call */
rv = xpcom_object->Method();
/* this is the catch block */
if (NS_FAILED(rv)) {
switch (rv) {
/* Components.results is a bad reflection of a limited set of
nsresult values, in C++,
* you get as many as you include, in JS you need to do something
like
* http://viper.haque.net/~timeless/nsError.js if you want things
that aren't reflected.
*/
case NS_ERROR_FILE_UNRECOGNIZED_PATH:
/* Assuming DoSomething is an XPCOM type method we need to catch
its return value
* since in js that would automatically result in a throw.
*/
rv = DoSomething();
/* if the return value from DoSomething() is NS_OK,
* then we're returning that non exceptional value
* otherwise we're returning the thrown exception.
*/
return rv;
case NS_ERROR_FILE_UNRESOLVABLE_SYMLINK:
/* here we're throwing a different exception value, just as the
js does */
return NS_ERROR_FILE_EXECUTION_FAILED:
case NS_ERROR_FILE_UNKNOWN_TYPE:
/* here we're rethrowing the same exception value we got, just as
the js does */
return rv;
default:
/* this is equivalent to if (NS_FAILED(rv)) { DoSomethingElse() }
which is what you would
* normally see in C++ code, but I've left it in a default just
to show that you can make life
* complicated if you want to.
*/
rv = DoSomethingElse();
return rv;
}
}
}
/* this is equivalent to any non throw in JS,
* which is the normal implicit return undefined at the end of the js
function.
*/
return NS_OK;
}

Mitchi

unread,
Dec 12, 2006, 7:02:10 AM12/12/06
to
Thanks for this code. It'll be really useful.

Ok. You can call me dumb or whatever you want, but I'm still working on
this

Yesterday, I finally could call the method of my component instanced in
javascript (hoorray!). It has been hard for me (well, i first heard
about XPCOM at the beginning of october), but I'm getting into it.

My simple component is done in javascript, but to implement the
functionality i need it in c++ so i'll start using your code to begin
the 'translation'.

At last I also needed to implement nsISecurityCheckedComponent to make
it work (not only nsIClassInfo).

I promise i'll write a tutorial-for-dumbs as soon as I make it work in
c++, containing both javascript and c++ implementations, but I'll need
some time. Please, be patient.

Regards.

timeless ha escrito:

0 new messages