Jalview-JS/JAL-3253-applet adds shell JalviewJSApi methods to Jalview
authorhansonr <hansonr@STO24954W.ad.stolaf.edu>
Sat, 18 May 2019 06:16:14 +0000 (01:16 -0500)
committerhansonr <hansonr@STO24954W.ad.stolaf.edu>
Sat, 18 May 2019 06:16:14 +0000 (01:16 -0500)
A starting point for introducing a JavaScript API for Jalview.

JalviewApplet.js now automatically creates a "LiveConnect-like" set
 of unqualified methods when the main class has a getInstance()
 method, using reflection to get that instance's method list and
 then using that list to create an interface that allows
 overloading of methods (as long as they have a different arity.

 So, for example, if Jalview is started as the "jalview1" applet
  (using the <applet> or <jvapplet> tag), then we have:

 Jalview1.setSelectionListener(alignFrame, listener)
 Jalview1.setSelectionListener(listener)

 and about 50 other methods.

 To keep this simple, all methods that are not private, not
 static, and that do not start with $ are included in the interface.

site-resources/swingjs/JalviewApplet.js
src/jalview/bin/Jalview.java
swingjs/SwingJS-site.zip
swingjs/timestamp
swingjs/ver/3.2.4/SwingJS-site.zip
swingjs/ver/3.2.4/timestamp

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");
+}
index c27d7af..ac6fcd6 100755 (executable)
@@ -44,6 +44,7 @@ import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
 import jalview.io.NewickFile;
 import jalview.io.gff.SequenceOntologyFactory;
+import jalview.javascript.JalviewLiteJsApi;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.util.MessageManager;
@@ -94,7 +95,7 @@ import groovy.util.GroovyScriptEngine;
  * @author $author$
  * @version $Revision$
  */
-public class Jalview implements ApplicationSingletonI
+public class Jalview implements ApplicationSingletonI, JalviewLiteJsApi
 {
 
   public static Jalview getInstance()
@@ -1381,4 +1382,416 @@ public class Jalview implements ApplicationSingletonI
     new JalviewAppLoader(true).load(app);
   }
 
+  @Override
+  public String getSelectedSequences()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getSelectedSequences(String sep)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getSelectedSequencesFrom(jalview.appletgui.AlignFrame alf)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getSelectedSequencesFrom(jalview.appletgui.AlignFrame alf,
+          String sep)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void highlight(String sequenceId, String position,
+          String alignedPosition)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void highlightIn(jalview.appletgui.AlignFrame alf,
+          String sequenceId, String position, String alignedPosition)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void select(String sequenceIds, String columns)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void select(String sequenceIds, String columns, String sep)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void selectIn(jalview.appletgui.AlignFrame alf, String sequenceIds,
+          String columns)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void selectIn(jalview.appletgui.AlignFrame alf, String sequenceIds,
+          String columns, String sep)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public String getSelectedSequencesAsAlignment(String format,
+          String suffix)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getSelectedSequencesAsAlignmentFrom(
+          jalview.appletgui.AlignFrame alf, String format, String suffix)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignmentOrder()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignmentOrderFrom(jalview.appletgui.AlignFrame alf)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignmentOrderFrom(jalview.appletgui.AlignFrame alf,
+          String sep)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String orderBy(String order, String undoName)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String orderBy(String order, String undoName, String sep)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String orderAlignmentBy(jalview.appletgui.AlignFrame alf,
+          String order, String undoName, String sep)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignment(String format)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignmentFrom(jalview.appletgui.AlignFrame alf,
+          String format)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignment(String format, String suffix)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAlignmentFrom(jalview.appletgui.AlignFrame alf,
+          String format, String suffix)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void loadAnnotation(String annotation)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void loadAnnotationFrom(jalview.appletgui.AlignFrame alf,
+          String annotation)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void loadFeatures(String features, boolean autoenabledisplay)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public boolean loadFeaturesFrom(jalview.appletgui.AlignFrame alf,
+          String features, boolean autoenabledisplay)
+  {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+  @Override
+  public String getFeatures(String format)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getFeaturesFrom(jalview.appletgui.AlignFrame alf,
+          String format)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAnnotation()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getAnnotationFrom(jalview.appletgui.AlignFrame alf)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public jalview.appletgui.AlignFrame newView()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public jalview.appletgui.AlignFrame newView(String name)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public jalview.appletgui.AlignFrame newViewFrom(
+          jalview.appletgui.AlignFrame alf)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public jalview.appletgui.AlignFrame newViewFrom(
+          jalview.appletgui.AlignFrame alf, String name)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public jalview.appletgui.AlignFrame loadAlignment(String text,
+          String title)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void setMouseoverListener(String listener)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void setMouseoverListener(jalview.appletgui.AlignFrame af,
+          String listener)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void setSelectionListener(String listener)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void setSelectionListener(jalview.appletgui.AlignFrame af,
+          String listener)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void setStructureListener(String listener, String modelSet)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void removeJavascriptListener(jalview.appletgui.AlignFrame af,
+          String listener)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void mouseOverStructure(String pdbResNum, String chain,
+          String pdbfile)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public boolean addPdbFile(jalview.appletgui.AlignFrame alFrame,
+          String sequenceId, String pdbEntryString, String pdbFile)
+  {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+  @Override
+  public void scrollViewToIn(jalview.appletgui.AlignFrame alf,
+          String topRow, String leftHandColumn)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void scrollViewToRowIn(jalview.appletgui.AlignFrame alf,
+          String topRow)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void scrollViewToColumnIn(jalview.appletgui.AlignFrame alf,
+          String leftHandColumn)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public String getFeatureGroups()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getFeatureGroupsOn(jalview.appletgui.AlignFrame alf)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getFeatureGroupsOfState(boolean visible)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getFeatureGroupsOfStateOn(jalview.appletgui.AlignFrame alf,
+          boolean visible)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void setFeatureGroupStateOn(jalview.appletgui.AlignFrame alf,
+          String groups, boolean state)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void setFeatureGroupState(String groups, boolean state)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public String getSeparator()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void setSeparator(String separator)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public String getJsMessage(String messageclass, String viewId)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
 }
index 51276f9..1f22365 100644 (file)
Binary files a/swingjs/SwingJS-site.zip and b/swingjs/SwingJS-site.zip differ
index 324f5c1..3c01637 100644 (file)
@@ -1 +1 @@
-20190516132838 
+20190518005924 
index 51276f9..1f22365 100644 (file)
Binary files a/swingjs/ver/3.2.4/SwingJS-site.zip and b/swingjs/ver/3.2.4/SwingJS-site.zip differ
index 324f5c1..3c01637 100644 (file)
@@ -1 +1 @@
-20190516132838 
+20190518005924