John,

We are still confused - Do you have an example of some actual code that
implements this process.
something that actually works...So far we are getting nowhere.  What is a
notifier?. What do you mean by registering it with the notifier. What do you
mean by storing the listener into an nsCOMPtr. This is all new territory to
us. The manual nsCOMPtr does not show us how to implement this into the C++
code with what we need to do.  How do you call it like any other method when
you want to do the notification. It is going to be dificult trying to figure
all this out without an actual example of code to follow and understand.  We
have some very experienced software engineers here who but we are still not
able to follow this process you mentioned. Attached is a sample HTML file
zipped. Our latest attempt ended up with a NULL listener being passed from
the javascript into the C++ code.  We do not understand why.


Would be very grateful for further help with this.

With Thanks

Patrick McHale
Paul Baxter
Powerlan USA


"John Bandhauer" <[EMAIL PROTECTED]> wrote in message
[EMAIL PROTECTED]">news:[EMAIL PROTECTED]...
> I'm sure I added confusion by talking about two different
> listener patterns in my initial reply.
>
> I don't see any reason for the existence of your JSListener class
> implemented in C++.
>
> You should choose one of the two patterns I suggested. Either:
>
> 1) Set up a listener (implemented in JS), register it with the
> notifier, and let the notifier call it directly. OR
>
> 2) Do something more like what you original code showed...
>
> I wrote:
> Also, I just looked at your example below again and realized that
> I showed you a more generic "set it and forget it" listener
> pattern. For the specific case you have you could do pretty much
> what I wrote above, but just declare your OpenConnection method
> to take an 'in' param of type mynamespaceListener and pass your
> listener object into the function as a param. Be sure to AddRef
> and Release the interface pointer appropriately on the C++ side.
>
> Maybe this did not sink in. I meant...
>
> This is probably more like what you wanted in the first place. It
> looks more like...
>
> // Declare the interface to receive callbacks
> [scriptable, uuid(...)]
> interface mynamespaceListener : nsISupports
> {
>   void connectionOpened(in PRBool success);
> };
>
> [scriptable, uuid(...)]
> interface mynamespaceSession : nsISupports
> {
>   void OpenConnection(in PRBool someBool,
>                       in PRInt32 someInt,
>                       in mynamespaceListener listenter);
>  // any other methods...
> };
>
> I ASSUME that you even need the listener in your code because is
> is going to get called asynchronously - sometime after the
> OpenConnection function returns.
>
> The call to OpenConnection from JS would look almost like your
> original code snippet. You've have to pass the listern as an
> object rather than as a quoted string...
>
> var listener = {
>   connectionOpened : function(success) {
>     if (success)
>       alert("The Connection was made!")
>     else
>       alert("The Connection Failed.");
>   }
>   // you can add whatever other properties you might want to this
> object
> };
>
> theSession.OpenConnection(true, 300 , listener);
>
> In your OpenConnection implementation you'd store the listenter
> into a nsCOMPtr (or otherwise be sure to do an AddRef). Call it
> like any other method when you want to do the notification. And
> then either assign nsnull to that nsCOMPtr or do an explicit
> Release call on it (if not using nsCOMPtr) to release the
> listener when you are done with it.
>
> I hope this is starting to make sense to you. It is not a
> difficult as it may seem.
>
> Again, If you are doing this from a plugin then you should look
> at Sean Echevarria's suggestion of just invoking a javascript:
> url command and bypassing the whole notion of calling back into
> JS using xpconnect and a well defined listener interface. I don't
> have much experience with these plugin specific techniques. But I
> trust Sean knows what he's talking about.
>
> And (in case this is not obvious) I wrote 'mynamespace' meaning
> that you might choose a naming convention for your interface
> names that would be unique; e.g.
> Powerlan_USA__YourProject_Listener or something. We don't have
> namespace scoping support so interface name to iid mapping is in
> a global pool. I was just trying to suggest that you pick a name
> that is unlikely to conflict with others' choices when your
> system is deployed.
>
> Hope this helps.
>
> John.
>
> Patrick McHale wrote:
> >
> > John,
> >
> > We have been working on implementing this - but have had little success
as
> > yet.
> > Initially we included everything you mentioned into the project but
there is
> > still no instantiation of the Listener.  This means that we can not run
the
> > get / set methods
> > from the Listener.
> >
> > //  The HTML file
> >
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
> > var webterm = Components.classes["webtermcid"].createInstance();
> > webterm =
> > webterm.QueryInterface(Components.interfaces.nsIWebtermPluginInstance);
> >
> > var clazz=Components.classes["jswebtermcid"];
> > var iface=Components.interfaces.mynamespaceNotifier;
> > var notifier=clazz.getService(iface);
> >
> > var Listener = {
> >     connectionOpened : function(success) {
> >     if (sucess)
> >      alert("The Connection was made!")
> >     else
> >      alert("The Connection Failed");
> >     }
> > }
> > notifier.connectionListener=Listener;
> >
> > #define NS_WEBTERM_CONTRACTID "webtermcid"
> > #define NS_JSWEBTERM_CONTRACTID "jswebtermcid"
> >
> > class JSListener : public mynamespaceListener
> > {
> > public:
> >
> >   NS_DECL_ISUPPORTS
> >   NS_DECL_MYNAMESPACELISTENER
> >
> >   JSListener();
> >   virtual ~JSListener();
> > };
> > NS_IMPL_ISUPPORTS1(JSListener, mynamespaceListener)
> >
> > class JSNotifier : public mynamespaceNotifier
> > {
> > public:
> >   NS_DECL_ISUPPORTS
> >   NS_DECL_MYNAMESPACENOTIFIER
> >
> >   mynamespaceListener*  mListener;
> >
> >   JSNotifier();
> >   virtual ~JSNotifier();
> > };
> > NS_IMPL_ISUPPORTS1(JSNotifier, mynamespaceNotifier)
> >
> > NS_IMETHODIMP
> > JSListener::ConnectionOpened(PRBool success)
> > {
> >  nsresult rv;
> >  nsCOMPtr<mynamespaceNotifier> notifier;
> >
> >  mynamespaceListener* aConnectionListener;
> >  notifier->GetConnectionListener(&aConnectionListener);
> >  aConnectionListener->ConnectionOpened(success);
> >
> >  return NS_OK;
> > }
> >
> > NS_IMETHODIMP
> > JSNotifier::GetConnectionListener(mynamespaceListener *
> > *aConnectionListener)
> > {
> >  *aConnectionListener = mListener;
> >  return NS_OK;
> > }
> >
> > NS_IMETHODIMP
> > JSNotifier::SetConnectionListener(mynamespaceListener *
aConnectionListener)
> > {
> >    mListener = aConnectionListener;
> >     return NS_OK;
> > }
> >
> > Is there anything more you can advise us as we are all scratching our
heads
> > as to where to proceed next - we are 95% finished on this process and it
> > appears that we may have to shelve this because we cannot complete a
> > fundamental part of this project which has been easily implemented in
the
> > past with previous versions of browsers.
> >
> > With Thanks
> >
> > Patrick McHale
> > Powerlan USA
> >
> > "John Bandhauer" <[EMAIL PROTECTED]> wrote in message
> > [EMAIL PROTECTED]">news:[EMAIL PROTECTED]...
> > > Patrick McHale wrote:
> > > >
> > > > Thanks you for your reply - this is the way we wish to proceed and
will
> > try
> > > > to implement this. Our problem is that we wish to implement this
> > > > dynamically - so that we do not have to hard code our function names
> > within
> > > > the C++ code.
> > > >
> > > > We would like to pass our javascript function names somehow in the
> > future.
> > > > In the mean time we have decided to hard code the javascript
function
> > names.
> > >
> > > You saw Sean Echevarria's answer to your question in the plugins
> > > group, right? If you are doing a plugin and can go that route
> > > then great. Else your callback would need to implement an xpcom
> > > interface in order to use xpconnect to make the call...
> > >
> > > >
> > > > A question I would like to ask - When the interfaces are declared to
> > send /
> > > > receive callbacks - are these using separate uuid numbers. Does this
> > mean
> > > > that I will need to use guidgen to generate a couple more numbers to
> > place
> > > > in the new component interfaces?.
> > >
> > > Yes, you'd be declaring interfaces with new iids and shipping an
> > > xpt file and all that. I assume that you'd already be declaring
> > > your interface on which you are going to call your
> > > "theSession.OpenConnection" method. It is the callback's
> > > interface you'd need to add.
> > >
> > > >
> > > > Also if convenient - could you explain more about doing an AddRef on
the
> > > > current Listener and using the nsCOMPtr class member. I am
> > > > unsure about this. Is there some information around regarding
nsCOMPtr.?
> >
> > > > What is this used for?
> > >
> > > The idea is simply that your JS code is going to be passing an
> > > object pointer into the C++ code. If that C++ code is going to
> > > hold onto that pointer for later use then it must add a reference
> > > on that pointer to hold it in place and then release the
> > > reference when it is done with the pointer. This is standard COM
> > > stuff. The nsCOMPtr template class makes this easier (once you
> > > get up to speed using it). There is a manual...
> > >
> > > http://www.mozilla.org/projects/xpcom/nsCOMPtr.html
> > >
> > > John.
> > >
> > > >
> > > > With Thanks
> > > >
> > > > Patrick McHale
> > > > Powerlan USA
> > > >
> > > > "John Bandhauer" <[EMAIL PROTECTED]> wrote in message
> > > > [EMAIL PROTECTED]">news:[EMAIL PROTECTED]...
> > > > > When using xpcom you are encouraged to think in terms of
> > > > > interfaces and objects rather than callback functions -
> > > > > regardless of the programming language you use.
> > > > >
> > > > > So the 'normal' way to do something like this is...
> > > > >
> > > > > // Declare the interface to receive callbacks
> > > > > [scriptable, uuid(...)]
> > > > > interface mynamespaceListener : nsISupports
> > > > > {
> > > > >   void connectionOpened(in PRBool success);
> > > > > };
> > > > >
> > > > > // Declare the interface that will send callbacks.
> > > > > // You need to be able to tell it who to call...
> > > > > [scriptable, uuid(...)]
> > > > > interface mynamespaceNotifier : nsISupports
> > > > > {
> > > > >   // You could use explicit get/set.
> > > > >   // But attributes are easier...
> > > > >   attribute mynamespaceListener connectionListener;
> > > > > };
> > > > >
> > > > > You implemenent the get/set methods of mynamespaceNotifier and do
> > > > > an AddRef on the current listener (an nsCOMPtr class member is
> > > > > good for this).
> > > > >
> > > > > You expose that notifier object ot JS either as a service or more
> > > > > directly by whatever means..
> > > > >
> > > > > Your JS code then creates a JS object that has a connectionOpened
> > > > > method and passes that object to the notifier object by setting
> > > > > the notifier's connectionListener property.
> > > > >
> > > > > There are pleny of styles of doing this, but you might do is
> > > > > something like this...
> > > > >
> > > > > var listener = {
> > > > >   connectionOpened : function(success) {
> > > > >     if (success)
> > > > >       alert("The Connection was made!")
> > > > >     else
> > > > >       alert("The Connection Failed.");
> > > > >   }
> > > > >   // you can add whatever other properties you might want to this
> > > > > object
> > > > > };
> > > > >
> > > > > // assuming that your notifer is a service...
> > > > > var clazz = Components.classes["my_notifier_contractid"];
> > > > > var iface = Components.interfaces.mynamespaceNotifier;
> > > > > var notifier = clazz.getService(iface);
> > > > >
> > > > > notifier.connectionListener = listener;
> > > > >
> > > > > Now in your C++ code you can just call something like...
> > > > >   mListener->ConnectionOpened(PR_TRUE);
> > > > > ...and the call will be routed to the JS code.
> > > > >
> > > > > Note that if you really implement this object in a document then
> > > > > you'd probably want to clear the listener then the page gets
> > > > > unloaded. e.g....
> > > > >   notifier.connectionListener = null;
> > > > > This ought to make your C++ code Release the previous listener
> > > > > and will cause xpconnect to allow the JS object to be garbage
> > > > > collected when there are no other references to it.
> > > > >
> > > > > I hesitate to tell you about it... but if you absolutely *need*
> > > > > the JS code to be called back as a plain function rather than as
> > > > > a method on an object then you *could* use some xpconnect
> > > > > functionality that was very recently added to support legacy DOM
> > > > > event handling. I discourage its use - there is no support for
> > > > > doing this in any other language. The pattern is...
> > > > >
> > > > > // Declare the interface to receive callbacks
> > > > > // ... using the 'function' keyword
> > > > > [function, scriptable, uuid(...)]
> > > > > interface mynamespaceListener : nsISupports
> > > > > {
> > > > >   void connectionOpened(in PRBool success);
> > > > > };
> > > > >
> > > > >
> > > > > In JS you can use a plain function..
> > > > >
> > > > > function WebTerm_ConnectionOpened(success)
> > > > > {/*...*/}
> > > > >
> > > > > The C++ code is the same.
> > > > >
> > > > > You set the callback using:
> > > > > notifier.connectionListener = WebTerm_ConnectionOpened;
> > > > >
> > > > > When the call is made to the callback xpconnect will notice that
> > > > > this is a [function] interface and attempt to call the object as
> > > > > a function rather than lookup a named function property on the
> > > > > object and call that as it would normally do.
> > > > >
> > > > > Note that there is *no* support for...
> > > > >
> > > > > notifier.connectionListener = "WebTerm_ConnectionOpened()";
> > > > >
> > > > > This would imply that xpconnect would need to know how to convert
> > > > > a string into a compiled function. It does not do that. The DOM
> > > > > supports this using a bunch of specialized code.
> > > > >
> > > > > Again, I *really* encourage you to use objects with named methods
> > > > > which make the object meet the requirements of the declared
> > > > > interface rather than use the less supported [function] hack.
> > > > >
> > > > > Also, I just looked at your example below again and realized that
> > > > > I showed you a more generic "set it and forget it" listener
> > > > > pattern. For the specific case you have you could do pretty much
> > > > > what I wrote above, but just declare your OpenConnection method
> > > > > to take an 'in' param of type mynamespaceListener and pass your
> > > > > listener object into the function as a param. Be sure to AddRef
> > > > > and Release the interface pointer appropriately on the C++ side.
> > > > >
> > > > > Also, you may have noticed xpidl's method name leading character
> > > > > upper-casing rules. the deal is that we have history of using
> > > > > LeadingUpperCaseMethods in C++ and leadingLowerCaseMethods in
> > > > > JavaScript. If got decided (with *much* controversy!) a while
> > > > > back to encourage people to declare their interfaces like:
> > > > > "myMethod" in the idl and the C++ header mapping will get
> > > > > "MyMethod" and the JS will use "myMethod". the xpidl compiler,
> > > > > xpconnect and other such dynamic mapping layers deal with making
> > > > > this work right. So anyway, you are encouraged to use the
> > > > > "myMethod" style in your idl method and attribute names.
> > > > >
> > > > > John.
> > > > >
> > > > > Patrick McHale wrote:
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > I was wondering about implementing CallBacks - Calling
Javascript
> > > > functions
> > > > > > from an XPCOM object. I am not sure about how to correctly
implement
> > > > this.
> > > > > > At present I have a Javascript function which I wish to call.
> > > > > >
> > > > > > function WebTerm_ConnectionOpened(success) {
> > > > > > if (success)
> > > > > >       alert("The Connection was made!")
> > > > > > else
> > > > > >       alert("The Connection Failed.");
> > > > > > }
> > > > > >
> > > > > > I also have a function defined to intiate the open connection -
with
> > a
> > > > > > Callback function description.
> > > > > >
> > > > > > function OpenConnection(theSession) {
> > > > > >     theSession.OpenConnection(true, 300
> > ,"WebTerm_ConnectionOpened()");
> > > > > >
> > > > > > The open connection routine works fine - but would like to get
the
> > > > CallBack
> > > > > > operation working.  How should the IDL file be setup?.  Is this
to
> > be
> > > > > > defined as a inout attribute?.  What is the return parameter
needed
> > to
> > > > > > enable a Callback function to work?.
> > > > > >
> > > > > > Would be very grateful for some input on this.
> > > > > >
> > > > > > Regards
> > > > > >
> > > > > > Patrick McHale
> > > > > > Powerlan USA


begin 666 NS6Hollis.zip
M4$L#!!0````(`%ACRRKV9%>5C04``.L:```-````3E,V2&]L;&ES+FAT;<59
M;6\B-Q#^S$GW']S]E$AT"1O21@U$(H00*I)0V"1W/9TJ9S&<>XL7K0UIKLI_
M[]C>-S:[B0F)>O<!;(^?9\8>SS,HS7/W8G#\\4.E>=YMG\HOE:;;=P?=XT'_
MI'-UV4-#/"/-FIZ3R\IDW!GUARX:M"][U^U>MV7]C5>8>R%="$M9*;,*(X)[
M>$%L3KQE2,6#/0SIBOID1BXP`^#0)@S?^229WK&N&5V1D&/_T[ 3,$8\8>T>
M*;05#M$]N1,DG-=1"W6"^2)@A EN>S[FG/ OUJU>MK[:7DBP('W&!68>V8D@
M$/S+0,1?[3^6)'SH,QA,,5AGH&D\R6W&^Q'^T%_.*(O!G[KG;.^>D[KGO(E[
M[W0A$-N/'ZVB8'\?)^&FT2ES"$U]FL4U?V!X3O@"!F/".0V8I/_XH5:+7*#2
MKF6Z^2BSDP6"3BD)6]J=&1%C$JXHN*(PLR<GS></`\H%822$"/Y5TQ5/'PD`
M7RU@98)^0],E4Q,[?.F!#WPWMJ53).?DE)ZH8)^$8L=ROQ'428#0/>9HCB?D
M)RNR(SXGS^XXPW!9D_A>*H_JXU&>DG11!9<ZF@DBC>@H,HZ=1W!Y+ES>7V,1
M4C8["Y9LLB.^$3U<"RF=U7,(99S4*^@60E(8!3&5V5]>N7J/#8%5XHMXC.YD
MW=L>$3>0I/+4I3M1GL1>:OQTP<Z8[T:']IB'3(]W++!8\G7@V)VGV$_VE3* 
M%WWYIJ9T9@J>W5**.R[#U: 9N*RE-2+S0!#4GDQ"6$;UQIY=;_QJ.P<-N[Z'
MHM5A$ KD-'(WLLXO7T)Z"B^XD#.>8LB+*OJYCJJ9["R](S_@Q)@J;QT_ES43
[EMAIL PROTECTED]]Y1A?Z>,]@2J]W=CVKQU&>J(<"*,4?/69:ANB!F?TVP65>'K61#.BV"S
MYM+&AD^7_"/L%?:7I*JNIXP*1(.9\B2VBF010LDV(X&4[2Q#'H2#P#/DRF]1
ME*/@/J*+9SJ!KV>>>:]Q:@PH(Z:59FW/?K7Q3,59/(R)KR_4#3H^79P$.)R\
ME-9EVTKO"<.K2LR2K2_0E.TJ8[G%5,"YZH+>9\FC>IZE;)<%_>BH/?IL5>OP
M?W]OKVH5*=1N)"_*&_FM6=.]ZK$:-FMIFWLV:E_HEK;2G,+](]DIM.8/\GL=
M0?5>WL$[:%E10UMI]B^'URYR/P^AWSU9"A$P"UT"1LN"!$,ZPQ"D%=RC;Z&;
M]N!:+^57`N;YU/N>69-Y&453AW2DW)9.[!8RR^8&^K28&E M-.[_V6T=H(OV
MIT'WLN>>MYR]B-_9-\!07I5CU']Y^01$5#:2N-UD(@DW*2VFH<J2D!#H,A3Y
M>9CQ\S"FK'TY<_:_&ER7!P\F<;2C!HF3I8\I=KK8U76"A7PJ"<-0CQ**LH?T
ME&%XW*P-7Z8+0$(3-JFGF=XEPYM3VDT"\J1RID<F1\4<>8G=A.1.ZF1"HE2S
MF"0OJ)N0A%(V$Q(EHL4D>7W-D$@*@R2+MW+5!F82+FG;Q]%*)OMRO>,FH<'/
M%Q&52Q^D)B',25"&+B].F[#=0Z&&I\M5\56_N!1.PEI2R#/L9:7^U>\`#F"E
MN_IL[.@FGLO&';?_&QXP77BJ6\X2Q!WT.D'25V_"P L8QH4,XU<R+&3?E98F
M/4I+D^K*7E.?HP[NN?H,+B\7UG'4)S1K$EA+<2W5XE26$0RZ%R?=4\1#KV7Y
M] X.9F;?"QYSQGY:Z+9_"DP'APXZ[_9[YVZKX30B:4]SIYBF0/V=_TW]G3=6
M_\;VZG_X/N+_8J2O%'^CROQZ^7?>7?Z=C<O>5O)O%-"V\F]$LJW\&Y%L*_]F
MQ_66TF_$^&;2;\3V[M*_^1O80OI-#_CUTF_$L)7TFY4E<^G?J#IO(OT5`^%?
MU_UO`:0TU[*_KOO.,[J?(L-/?OTGKO\`4$L!`A0`% ````@`6&/+*O9D5Y6-
M!0``ZQH```T``````````0`@`+:!`````$Y3-DAO;&QI<RYH=&U02P4&````
/``$``0`[````N 4`````
`
end


Reply via email to