Leap-frogging here....


On Mon, Jul 16, 2012 at 6:31 AM, Gusts Kaksis <gusts.kaksis@gmail.com> wrote:
>
> We need this class to overcome stupid "functionName"-as-a-string passed to Java Applet
>
> Note that JmolApi does access the function directly, but I don't know
> that there is an alternative to sending  a String to the Java applet.
> This function name is (or can be) set by Jmol scripting, so it starts
> as a String and is saved as a String. Within Java we just access the
> method with that name. Are you thinking there's a way around that?
There isn't. Saddly this is the way web and plugins work together, even
in ActionScript you have to call ExternalInterface.call("functionName",
someParam); Which is kinda stupid, that you cannot send a
pointer/reference to a real function. But I think it's because of the
way JavaScript is - it's an interpreted scripting language, so there are
no real function hanging somewhere in RAM, that's why you have to use
string name from Java side, and the browser looks it up in some kind of
hash table of functions.


Java can save the JSObject for the function. We could do that; we just don't. I don't think once the function is parsed it is in string form anymore. Evidence of this is that at least with MSIE the function string version is different from what the user typed. Like the way tags are not string anymore after HTML is parsed. They are part of the DOM at that point.


 
>
> _cbMeasure = function(id){
>               switch (arguments[3]){
>                       case 'measurePicked':
>
> I guess it's not clear to me why you are implementing callbacks in
> such a specific way. Page developers generally substitute in their own
> callbacks to handle their own specific needs. I guess some defaults
> like this might be handy, but it needs to be clear how someone would
> override these with their own methods. Remember that hover and pick
> callback messages can be tailored by the developer. I wouldn't be
> parsing that string. That's a real hack.
It's this one beautiful jQuery way of doing things - write less do more.
I'm translating all the callbacks into events, so that a developer can
subscribe to them and unsubscribe from them on the fly using jQuery
APIs, as esasy as : $('#jmol').bind('pick', myPickHandler); and
$('#jmol').unbind('pick'); And of course if you send a "set callbackName
functionName" script to Jmol then this event mechanism will be broken :(


Well, you need to figure out how to handle that, then, or there's a problem. Callbacks have to be scriptable.


 
What is the possible output from these callbacks (measure, hover, pick),
like what arguments can I expect and what do they mean?

see http://jmol.sourceforge.net/jslibrary/#jmolSetCallback

 
I just thought
that preparing a consequent data object for these callbacks are more
useful for a developer then a raw string. For example, hover and pick
methods send really simple data, that can be prepared as I've already
done.

But the format of those strings is totally programmable by the page developer. You are just using the default settings, so that amounts to a hack. Fine for a demo; not appropriate for a general solution.
 
The measurement is a little bit tougher, and there is really no
documentation on your site about all the parameters, so I was doing a
wild guess there. :)


yes, that's a bit hard to find: http://jmol.sourceforge.net/jslibrary/#jmolSetCallback
 
I know that you can call "set callbackName functionName", but if we're
doing it jQuery way, then events are more versatile than callbacks, as
you can bind multiple functions to the same event, which is not possible
with callbacks. At least I think it isn't, what's happening on Java side
there - does set callbackName overwrite previous callback function name?

Yes, it sets the callback function name to a new function.
 
> It's important to have a random number indicated as the sync id. Don't
> just assign 0. See JmolApi for several more defaults. Be sure to make
> it clear how one overrides these.
Random or unique? Because, if it's 0, a real number will be assigned in
_appletBuild method which is an applet counter (it increments every time
a new applet instance is created in page), that should be unique enough.
Or have I forgotten about some inter-window (or even inter-browser)
communication?

These need to be unique across an entire session, not just a page. Someone could easily have multiple pages with Jmol applets, and for rapid inter-applet communication we need to register the applets. Thus they need unique names. 10 digits of randomness is sufficient, though not perfect.

 
> The browser checking in Jmol.js and JmolApplet.js probably looks
> unnecessary to you, but the general philosophy is to make sure this
> runs on all browsers possible. There's a reason for that. I wouldn't
> mess with it. Just use JmolApi to deliver this, please.
This is just a template for HTML output. It's there for clarity,
everything else happens in _appletBuild, where I check the browser and
OS and, for example, add additional classid and codebase for IE, etc.
>
>                       + '<param name="appletReadyCallback" value="JmolCallbackWrapper.cbReady" />'
>                       + '<param name="hoverCallback" value="JmolCallbackWrapper.cbHover" />'
>                       + '<param name="loadStructCallback" value="JmolCallbackWrapper.cbLoad" />'
>                       + '<param name="pickCallback" value="JmolCallbackWrapper.cbPick" />'
>                       + '<param name="measureCallback" value="JmolCallbackWrapper.cbMeasure" />'
>                       + '<param name="syncCallback" value="JmolCallbackWrapper.cbSync" />'
>
>
>
> Well, if we can avoid creating multiple objects it would be better.
> How many primary objects are you creating here -- only
> JmolCallbackWrapper? Can that all be within "Jmol." ? Also, you don't
> necessarily do yourself a favor to generate unnecessary callbacks in
> Jmol. You are loading it up with callbacks when you don't know that
> the user is interested. That's just wasted communication.
It's more like a private class intended to intercept callbacks and
translate into events. It should never be used as a real class. And it's
static, so there is only one instance. As the Jmol itself sends an
ID/name of applets <object> tag, this class forwards all the calls to
the appropriate jQuery wrapper.


Take a look at what is done in JmolApplet.js. There is no issue of ID there. The applet is sent the correct function name up front for the callback, and that always goes to the proper _Applet straight away. No need for checking later. See if you can do this with out the _applets associative array.

 
As for communication, I agree, I should strip it down even more and use
"set callbackName functioName", only for now I can not intercept when
user calls jQuery's bind() method. I'll probably have to work on some
cheat here, like wrapping jQuery itself.

ouch.

 
>
>
>               /**
>               * It seems that "appletReadyCallback" return's an internal wrapper object
>               * Which we kindly store here to use instead of document.getElementById('some_applet') and then wonder
>               * why an object does not have a method for no reason.
>               */
>               _applets = {};
>
>
> yes, that's right, and it works great. That's what we do now in
> JmolApi. Not sure why you are doing anything with _applets.
I'm not, it's just my private variable, that i've named _applets (as in
Java applets, not <applets>)

I think you are using it to find the correct applet. This should not be necessary.


 
>
>                                               // Funny thing about Jmol Java applet :)
>                                               // Hacking is the way to the victory
>                                               _applets[id] = args[3];
>
> Agreed. I think that one got missed in the  documentation.
Thank god, we cleared up this one, so it's safe to use that 4th argument
as the real applet's interface.

It's just very new. Came  with JmolApplet.js and Jmol 12.3.
 
>
> On the ready signal, you need to send all cached scripts.
>
>               _appletScript = function(id, command){
>                       var applet = _appletFind(id);
>
> _appletFind is obsolete. The  idea is to always pass the object to the
> function so that there is no finding anything. This was a legacy
> default that has caused all sorts of grief and it is good to be done
> with it.
Umm, I'm not using any of Jmol.js methods, it's only my jQuery Jmol
plugin (as I said, it's completely standalone for now), without any
dependencies to Jmol.js or JmolApi.js at all. And _appletFind is my
private method to get an applet's interface from internal cache (array)
named _applets;

RIght. That's what I'm trying to avoid if possible. Can you set up a simple page with two applets and show us how we can query them in different ways and get different callbacks? For example, get the state from one and pass it to the other?



 
>
>                       html = html.replace('%script%', script);
>
>
> oooh, I really don't think that is going to work. You aren't escaping
> double quotes there. Basically we don't send script to the applet in
> param tags anymore. It just doesn't work reliably. Instead, take any
> script and append it to a growing script that needs to be sent when
> you receive the applet ready signal.
OK, script cache it is then. Thease scripts were intended only for 2
things - a menu file and initial model file which are simple commands
and you cannot write anything else, just initialize a jQuery plugin with
thease options set:

menuUrl : 'my_menu.mnu',
modelUrl : 'my_model.pdb'

and it translates into script variable like this:

menu my_menu.mnu;
load my_model.pdb


Nice for a demo; not of general use. People don't just load files, generally.
 
That's it, but we can turn it into cached script if you say, that it's
the new way of Jmol.
> Most importantly, you need to make sure you never access the applet
> except after its ready callback. no scripts sent; no queries made.
OK. I still need to work on callback setters when needed, and the only
callback that will be left at initialization time is ready callback.

It's the ready callback that probably should initialize all the other callbacks. Otherwise your buttons will be active prior to the applet being ready, and a press of a button could crash the browser. (really)


 
> Overall, I think it has great potential.
Thanks :)
>
> Q: Will changes to jQuery have to be made to ensure the applet never
> experiences CSS style.display = "none"?
I think this is close to impossible, as it can happen any way from a
different script, written by user.

It must not happen, and it must not be possible to do this inadvertently -- specifically because jQuery might happen to do this in some context the user is not aware of. This is absolutely necessary. I would say this is a major concern. Unfortunately, for many browsers it does not matter, so someone not testing on MSIE will think their page works great, and if they have, say, used jQuery extensively and built their page around some cool jQuery functionality such as tabbed divs, they could be in for a huge surprise way late in the game. So, if nothing else, we need to identify exactly when jQuery would do that and have very visible information for users to NOT use that particular functionality.

Just a quick look at an old jQuery code I have on hand:

                // Go through and make them visible, but in reverse
                // (It would be better if we knew the exact display type that they had)
                for ( var i = 0; i < stack.length; i++ )
                    if ( color( stack[ i ] ) ) {
                        swap[ i ] = stack[ i ].style.display;
                        stack[ i ].style.display = "block";
                    }

                // Since we flip the display style, we have to handle that
                // one special, otherwise get the value
                ret = name == "display" && swap[ stack.length - 1 ] != null ?
                    "none" :
                    ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";

                // Finally, revert the display styles back
                for ( var i = 0; i < swap.length; i++ )
                    if ( swap[ i ] != null )
                        stack[ i ].style.display = swap[ i ];


Death to the applet in MSIE.

Animation, for example, would probably be in this category.

 
> Q: Would you be willing to create a version that is built around
> JmolCore.js instead of Jmol.js?
Currently this code is completely stand alone, it does not use any of
Jmol's JavaScript APIs. I was thinking of leaving it that way, and maybe
propose you to use my solution as a replacement for JmolApplet.js. We
just need to agree on a few things if you wish.

Long range, that sounds good. If it were me, I'd build off JmolCore and then, once it all works, abandon JmolCore. Seems to me starting from scratch would be hugely more difficult. But that's just me.
 
>
> Q: What's your plan for integrating JME, JSpecView, and ChemDoodle
> into this?
I think it's doable, but I'd preffer to create them as a sepparate
projects. You see, jQuery Jmol is intended only as a building block for
<object> tag and a communication channel, everything else should be
developed by the user or implemented in Jmol's JavaScript APIs. Then I
could create jQuery JME for example which is also just a small building
block, that replaces a placeholder <div> with an <object> tag and
releases some communication channels to outside world, which can be
grabbed by higher level API and used.

The main issue in my mind is that functionality is not lost.

Bob
 

--
Gusts Kaksis


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Jmol-developers mailing list
Jmol-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-developers



--
Robert M. Hanson
Larson-Anderson Professor of Chemistry
Chair, Chemistry Department
St. Olaf College
Northfield, MN
http://www.stolaf.edu/people/hansonr


If nature does not answer first what we want,
it is better to take what answer we get.

-- Josiah Willard Gibbs, Lecture XXX, Monday, February 5, 1900