Jalview-JS/JAL-3253-applet adds shell JalviewJSApi methods to Jalview
[jalview.git] / site-resources / swingjs / JalviewApplet.js
index 872f8a0..f410ec3 100644 (file)
@@ -12,7 +12,7 @@ $(document).ready(function() {
 
  
 Jalview.processAllAppletElements = function(PageInfo) {
-       var applets = document.getElementsByTagName("applet") || document.getElementsByTagName("jvapplet");
+       var applets = document.getElementsByTagName("applet");
        var apps=[];
        for (var i = 0; i < applets.length; i++)
                apps[i] = applets[i];
@@ -23,50 +23,38 @@ Jalview.processAllAppletElements = function(PageInfo) {
  
 Jalview.processAppletElement = function(element, UserInfo) {
        
-       // This code is specifically for processing the <applet> or <jvapplet> tag.
-       
-       // To set Jalview application tags, use Info.args="......."
-
-       // To set preferences, use "jalview_" prefix with all-upper-case names:
-
-       //Info.jalview_SCREEN_X= 10,Info.jalview_SCREEN_Y= 10;
-       //Info.jalview_EMBEDDED= true;
-       //Info.jalview_SCREEN_WIDTH = 400;
-       //Info.jalview_SCREEN_HEIGHT = 100;
-       
-var text = element.outerHTML;
-var code = element.getAttribute("code");
-var parent = element.parentElement;
-if (code != "jalview.bin.JalviewLite" && text.indexOf("<applet") == 0) {
-       return;
-}
+       var code = element.getAttribute("code");
+       var parent = element.parentElement;
+       if (code != "jalview.bin.JalviewLite") {
+               return;
+       }
 
        var Info = {
-       code: null,
-       main: "jalview.bin.Jalview",
-       core: "NONE",
-       resourcePath: "examples",
-       readyFunction: null,
-       serverURL: 'https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php',
-       j2sPath: 'swingjs/j2s',
-       console:'sysout',
-       startButton:'Start Jalview',
-       hideDesktop:true,
-       embedInternalFrames:false,
-       idPrefix:'%ID%',
-       allowjavascript: true
+               code: null,
+               main: "jalview.bin.Jalview",
+               core: "NONE",
+               resourcePath: "examples",
+               readyFunction: null,
+               serverURL: 'https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php',
+               j2sPath: 'swingjs/j2s',
+               console:'sysout',
+               startButton:'Start Jalview',
+               hideDesktop:true,
+               embedInternalFrames:false,
+               idPrefix:'%ID%',
+               allowJavascript: true,
        }
 
-       var args = Info.args = text.replace(/[\n\t]/g, " ").replace("<jvapplet","<applet").split("<param ");
+       var text = element.outerHTML;
+       var args = Info.args = text.replace(/[\n\t]/g, " ").split("<param ");
 
-       // overwrite default parameters with UserInfo (global JalviewInfo):
+       // overwrite default parameters with UserInfo (global JalviewInfo):
  
        if (UserInfo) {
                for (var i in UserInfo) {
                        Info[i] = UserInfo[i];
                }
        }
-
        // generate name/value pairs for parameters in Applet tag
 
        Info.j2sAppletID = Info.j2sAppletID 
@@ -74,19 +62,24 @@ if (code != "jalview.bin.JalviewLite" && text.indexOf("<applet") == 0) {
                || element.getAttribute("id") 
                || Info.idPrefix.replace(/%ID%/g, "jalview" + ++Jalview.jvid);
        
+       //Info.jalview_SCREEN_X= 10,Info.jalview_SCREEN_Y= 10;
+       //Info.jalview_EMBEDDED= true;
+       //Info.jalview_SCREEN_WIDTH = 400;
+       //Info.jalview_SCREEN_HEIGHT = 100;
+
        
        var addParam = function(key,value) {
                args.push("name=\"" + key + "\" value=\"" + value + "\""); 
        }
-       
-       
+
+
        for (var i in Info) {
                var v = ("" + Info[i] || "null").replace(/\"/g,"'");
                addParam("Info." + i, v);
        }
-               
-               
        
+       
+
        element.JalviewInfo = Info;
        var btn = document.createElement("button");
        btn.appletElement = element;
@@ -100,7 +93,7 @@ if (code != "jalview.bin.JalviewLite" && text.indexOf("<applet") == 0) {
                parent.replaceChild(btn, element); 
                $(btn).click(Jalview.doStartJalview);
        } else {
-               parent.removeElement(element);
+               parent.removeChild(element);
                Jalview.doStartJalview({target:btn});
        }
 }
@@ -108,8 +101,9 @@ if (code != "jalview.bin.JalviewLite" && text.indexOf("<applet") == 0) {
 
 
 Jalview.doStartJalview = function(e) {
+       e.target.disabled = true;
        var element = e.target.appletElement;
-var parent = e.target.jvparent;
+       var parent = e.target.jvparent;
        var Info = element.JalviewInfo;
        var id = Info.j2sAppletID;
        var d = document.createElement("div");
@@ -129,8 +123,69 @@ var parent = e.target.jvparent;
                d.style.display = "none";
                d.style.width = d.style.height = "0px";
        }
-       SwingJS.getApplet(id, Info);
-       document.title = id;
-       e.target.style.visibility="hidden";
+       if (Info.allowJavascript) {
+               if (Info.readyFunction) {
+                       var c = Info.readyFunction;
+                       Info.readyFunction = function(a){
+                               Jalview._setAPI(a);
+                               c.apply(null, arguments);                       
+                       }
+               } else {
+                       Info.readyFunction = function(a) {Jalview._setAPI(a)};
+               }
+       }
+       var app = SwingJS.getApplet(id, Info);
 }
 
+Jalview._setAPI = function(app) {
+       
+       // Create a map of nonqualified methods to qualified methods
+       // based on parameter type.
+       var cl = Class.forName$S("jalview.bin.Jalview");
+       if (!cl.$clazz$.getInstance$) {
+               System.err.println(app.__Info.main + " has no getInstance() method; interface creation skipped.");
+               return;
+       }
+       var instance = app._instance = cl.$clazz$.getInstance$();
+       var apply = function(args, methods) {
+               return methods[args.length].apply(instance, args);
+       }
+       var getMap = function(cl) {
+               var methods = cl.getMethods$();
+               var p = cl.$clazz$.prototype;
+               var map = {};
+               for (var i = 0, n = methods.length; i < n; i++) {
+                       var qname = methods[i].name; 
+                       if (cl.$clazz$[qname])
+                               continue; // static method
+                       var s = qname.split("$");
+                       var name = s[0];
+                       if (!name)
+                               continue; // $init$, $cinit$
+                       if (app[name]) {
+                               name += "$";
+                               System.err.println(app._id + "." + name + " is " + qname);
+                       };
+                       (m = map[name])||(m = map[name] = []);
+                       var j = p[qname].length;
+                       if (m[j]) {
+                               System.err.println(app._id + ".instance." + qname + " must be called directly.");
+                               app[qname] = p[qname];
+                       } else {
+                               System.out.println(app._id + "." + name + "(" + j + ") aliases " + app._id + ".instance." + qname);
+                               m[j] = p[qname];
+                       }
+               }
+               return map;
+       }
+       var getFunc = function(map,i) {
+               return function(){return apply(arguments,map[i])};
+       }
+       var map = getMap(Clazz._4Name(app.__Info.main));
+       var n = 0;
+       for (var i in map) {
+               n++;
+               app[i] = getFunc(map,i);
+       }
+       System.err.println(app._id + " contains " + n + " JavaScript interface methods");
+}