From: Gusts K. <gus...@gm...> - 2012-07-16 11:32:06
|
> OK, taking a look now at http://gusc.lv/jmol/assets/js/jquery.jmol.js > > So I think this is based on Jmol.js, not JmolCore.js, right? In any > case, some advice: Well, it's kinda based, I just looked up a few things - like what methods are available through public interface from applet to JavaScript and HTML <param> tag options for setting callbacks and initializing some colors etc. > > 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. > > _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 :( What is the possible output from these callbacks (measure, hover, pick), like what arguments can I expect and what do they mean? 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. 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. :) 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? > 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? > 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. 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. > > > /** > * 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>) > > // 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. > > 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; > > 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 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. > 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. > 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. > > 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. -- Gusts Kaksis |