/* Jmol2.js (JSmol version) author: Bob Hanson hansonr@stolaf.edu 5/24/2013 12:06:25 PM Script replacement for legacy Jmol.js that uses JSmol instead. Can be used to turn most legacy Jmol.js-based sites to JSmol. BH 1/16/2014 10:33:46 PM adding serverURL indication, more notes BH 1/13/2014 11:14:12 AM incorrect default for missing jmolInitialize() (should be ".") BH 1/8/2014 5:56:15 AM simplified instructions; removed option for self.Info BH 11/12/2013 6:34:22 AM adds jmolAppletInline() BH 9/23/2013 10:07:16 PM adds set of loadInline functions BH 9/19/2013 7:09:41 AM fixed jmolSetTarget() to accept "0" as a suffix; use of undefined --> null Summary: You should not have to change any of your HTML pages. You are going to replace Jmol.js, wherever that is, with this file. You are going to replace all your JAR file with the ones in this distribution. You are going to add about 1000 files in the jsmol/j2s directory to your website. Don't worry; only a few will be called. But you won't know which ones. You will be able to switch from HTML5 to JAVA using ?_USE=SIGNED in the URL Procedure: 1a) If you want to use HTML5, copy all jsmol/j2s/* files into a j2s subdirectory in the directory that contains Jmol.js and your old Jmol jar files. 1b) If you are not using HTML5, change the "use" parameter below from "HTML5" to "JAVA" and save this file. Copy all the jsmol/java/* files into the directory containing your current JAR files. This adds four JNLP files as well and will replace all your JAR files. 2) Rename your current Jmol.js file Jmol_old.js in case you want to undo this. 3) Concatenate Jmol.min.js if you are not using jQuery (or Jmol.min.nojq.js if you are) with this file to form a new file (Jmol.min.js first, then Jmol2.js) and replace your current Jmol.js with it. Note that if you are using your own version of jQuery, it must be version 1.9 or higher, and note that 2.0 or higher will not work with MSIE used locally but accessing remote resources. See http://bugs.jquery.com/ticket/14876 4) Try your page and see how it goes. You may still have some problems, because not all of the methods in the original Jmol.js are included here. Let me know if that's the case. If you wish to change the directories your j2s or JAR files and override the default settings (old JAR file location; j2s directory in the directory of those JAR files) and thus override your current settings in your HTML files, then you can to that three ways: a) You can change the parameters below to override what your pages already use by uncommenting one or the other of the jarPath and j2sPath definitions. This will override jmolInitialize in ALL your HTML files. b) You can change your jmolInitialization call in an individual HTML file. This sets both the JAR path and the j2s path (as [jarPath]/j2s) together. c) You can add lines to an individual HTML file along the lines of: Jmol.Info.jarPath = "../../Jmol" Jmol.Info.j2sPath = "../../JSmol" or whatever. This will override jmolInitialize in that specific HTML file only. Note that: -- FireFox works great. You will be able to read binary files from your local machine -- Chrome can only read local files if started with the --allow-file-access-from-files flag and even then the files must be ASCII, not binary. -- MSIE and Safari cannot work with local pages */ /* $RCSfile: Jmol.js,v $ * $Author: migueljmol $ * $Date: 2004/12/11 22:22:10 $ * $Revision: 1.28 $ * * Copyright (C) 2004 The Jmol Development Team * * Contact: jmol-developers@lists.sf.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. */ // for documentation see www.jmol.org/jslibrary var undefined; // for IE 5 ... wherein undefined is undefined //////////////////////////////////////////////////////////////// // Basic Scripting infrastruture //////////////////////////////////////////////////////////////// function jmolInitialize(codebaseDirectory) { if (_jmol.initialized) { alert("jmolInitialize() should only be called *ONCE* within a page"); return; } if (! codebaseDirectory) { alert("codebaseDirectory is a required parameter to jmolInitialize"); codebaseDirectory = "."; } if (codebaseDirectory.indexOf("http://") == 0 || codebaseDirectory.indexOf("https://") == 0) alert("codebaseDirectory should be directory relative,\n" + "not be an absolute URL : " + codebaseDirectory); else if (codebaseDirectory.charAt(0) == '/') alert("codebaseDirectory should be directory relative,\n" + "not relative to the root of the web server : " + codebaseDirectory); _jmolSetCodebase(codebaseDirectory); _jmolOnloadResetForms(); _jmol.initialized = true; } function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) { _jmolInitCheck(); _jmol.boxbgcolor = boxbgcolor; if (boxfgcolor) _jmol.boxfgcolor = boxfgcolor else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF") _jmol.boxfgcolor = "black"; else _jmol.boxfgcolor = "white"; if (progresscolor) _jmol.progresscolor = progresscolor; if (_jmol.debugAlert) alert(" boxbgcolor=" + _jmol.boxbgcolor + " boxfgcolor=" + _jmol.boxfgcolor + " progresscolor=" + _jmol.progresscolor); } function jmolApplet(size, script, nameSuffix) { _jmolInitCheck(); _jmolApplet(size, null, script, nameSuffix); } //////////////////////////////////////////////////////////////// // Basic controls //////////////////////////////////////////////////////////////// function jmolButton(script, label, id) { _jmolInitCheck(); var scriptIndex = _jmolAddScript(script); if (label == undefined || label == null) label = script.substring(0, 32); if (id == undefined || id == null) id = "jmolButton" + _jmol.buttonCount; ++_jmol.buttonCount; var t = ""; if (_jmol.debugAlert) alert(t); document.write(t); } function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked, labelHtml, isChecked, id) { _jmolInitCheck(); if (id == undefined || id == null) id = "jmolCheckbox" + _jmol.checkboxCount; ++_jmol.checkboxCount; if (scriptWhenChecked == undefined || scriptWhenChecked == null || scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) { alert("jmolCheckbox requires two scripts"); return; } if (labelHtml == undefined || labelHtml == null) { alert("jmolCheckbox requires a label"); return; } var indexChecked = _jmolAddScript(scriptWhenChecked); var indexUnchecked = _jmolAddScript(scriptWhenUnchecked); var t = "" + labelHtml; if (_jmol.debugAlert) alert(t); document.write(t); } function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName) { _jmolInitCheck(); var type = typeof arrayOfRadioButtons; if (type != "object" || type == null || ! arrayOfRadioButtons.length) { alert("invalid arrayOfRadioButtons"); return; } if (separatorHtml == undefined || separatorHtml == null) separatorHtml = "  "; var length = arrayOfRadioButtons.length; var t = ""; jmolStartNewRadioGroup(); for (var i = 0; i < length; ++i) { var radio = arrayOfRadioButtons[i]; type = typeof radio; if (type == "object") { t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName); } else { t += _jmolRadio(radio, null, null, separatorHtml, groupName); } } if (_jmol.debugAlert) alert(t); document.write(t); } function jmolLink(script, text, id) { _jmolInitCheck(); if (id == undefined || id == null) id = "jmolLink" + _jmol.linkCount; ++_jmol.linkCount; var scriptIndex = _jmolAddScript(script); var t = "" + text + ""; if (_jmol.debugAlert) alert(t); document.write(t); } function jmolMenu(arrayOfMenuItems, size, id) { _jmolInitCheck(); if (id == undefined || id == null) id = "jmolMenu" + _jmol.menuCount; ++_jmol.menuCount; var type = typeof arrayOfMenuItems; if (type != null && type == "object" && arrayOfMenuItems.length) { var length = arrayOfMenuItems.length; if (typeof size != "number" || size == 1) size = null; else if (size < 0) size = length; var sizeText = size ? " size='" + size + "' " : ""; var t = "" + labelHtml + separatorHtml; } function _jmolFindApplet(target) { // first look for the target in the current window var applet = _jmolSearchFrames(window, target); if (applet == undefined) applet = _jmolSearchFrames(top, target); // look starting in top frame return applet; } function _jmolSearchFrames(win, target) { var applet; var frames = win.frames; if (frames && frames.length) { // look in all the frames below this window for (var i = 0; i < frames.length; ++i) { applet = _jmolSearchFrames(frames[i++], target); if (applet) break; } } else { // look for the applet in this window var doc = win.document; // getElementById fails on MacOSX Safari & Mozilla if (doc.applets) applet = doc.applets[target]; else applet = doc[target]; } return applet; } function _jmolAddScript(script) { if (! script) return 0; var index = _jmol.scripts.length; _jmol.scripts[index] = script; return index; } function _jmolClick(scriptIndex, targetSuffix) { jmolScript(_jmol.scripts[scriptIndex], targetSuffix); } function _jmolMenuSelected(menuObject, targetSuffix) { var scriptIndex = menuObject.value; if (scriptIndex != undefined) { jmolScript(_jmol.scripts[scriptIndex], targetSuffix); return; } var length = menuObject.length; if (typeof length == "number") { for (var i = 0; i < length; ++i) { if (menuObject[i].selected) { _jmolClick(menuObject[i].value, targetSuffix); return; } } } alert("?Que? menu selected bug #8734"); } function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) { _jmolClick(ckbox.checked ? whenChecked : whenUnchecked, targetSuffix); } function _jmolCbOver(ckbox, whenChecked, whenUnchecked) { window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked]; } function _jmolMouseOver(scriptIndex) { window.status = _jmol.scripts[scriptIndex]; } function _jmolMouseOut() { window.status = " "; return true; } function _jmolSetCodebase(codebase) { _jmol.codebase = codebase ? codebase : "."; if (_jmol.debugAlert) alert("jmolCodebase=" + _jmol.codebase); } function _jmolOnloadResetForms() { _jmol.previousOnloadHandler = window.onload; window.onload = function() { // alert("onloadResetForms"); with (_jmol) { if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) { var forms = document.forms; if (!forms || forms.length == 0) { alert("
tags seem to be missing\n" + "Jmol/HTML input controls must be contained " + "within form tags" // + "\n\n" + forms + " forms.length=" + forms.length + // " typeof=" + (typeof forms) ); } else { for (var i = forms.length; --i >= 0; ) forms[i].reset(); } } if (previousOnloadHandler) previousOnloadHandler(); } } } Jmol.Info = { // uncomment one or more of these next lines only if you want to override jmolInitialize() //jarPath: "java", //jarFile: "JmolAppletSigned0.jar", //j2sPath: "j2s", use: "JAVA", // could be JAVA or HTML5 // the serverURL path is only used to load binary files in Safari, Chrome, and MSIE serverURL: "https://www.chem.wisc.edu/deptfiles/genchem/netorial/modules/biomolecules/jmol-10.00/php/jsmol.php", // required for binary file loading (Spartan, .gz, .map, etc.) disableJ2SLoadMonitor: false, disableInitialConsole: true } ////////// private functions ///////////// var _jmol = { appletCount: 0, applets: {}, allowedJmolSize: [25, 2048, 300], // min, max, default (pixels) codebase: ".", targetSuffix: 0, target: "jmolApplet0", buttonCount: 0, checkboxCount: 0, linkCount: 0, cmdCount: 0, menuCount: 0, radioCount: 0, radioGroupCount: 0, initialized: false, initChecked: false, archivePath: "JmolAppletSigned0.jar" } function _jmolApplet(size, inlineModel, script, nameSuffix) { nameSuffix == null && (nameSuffix = _jmol.appletCount); var id = "jmolApplet" + nameSuffix; jmolSetTarget(nameSuffix); ++_jmol.appletCount; script || (script = "select *"); inlineModel && (script = 'load DATA "inline"\n' + inlineModel + '\nEND "inline";' + script); var Info = {} for (var i in Jmol.Info) Info[i] = Jmol.Info[i] Info.jarFile || (Info.jarFile = _jmol.archivePath); Info.jarPath || (Info.jarPath = _jmol.codebase); Info.j2sPath || (Info.j2sPath = Info.jarPath + "/j2s"); var sz = _jmolGetAppletSize(size); Info.width || (Info.width = sz[0]); Info.height || (Info.height = sz[1]); Info.script || (Info.script = script); Info.isSigned == null && (Info.isSigned = (Info.jarFile.indexOf("Signed") >= 0)); for (var i in _jmol.params) if(_jmol.params[i]!="") Info[i] || (Info[i] = _jmol.params[i]); // alert(JSON.stringify(Info).replace(/\,/g,"\n\n\n\n")) return _jmol.applets[id] = Jmol.getApplet(id, Info) } function _jmolGetJarFilename(fileNameOrFlag) { _jmol.archivePath = (typeof(fileNameOrFlag) == "string" ? fileNameOrFlag : (fileNameOrFlag ? "JmolAppletSigned" : "JmolApplet") + "0.jar"); } //////////////////////////////////////////////////////////////// // Legacy Scripting API //////////////////////////////////////////////////////////////// function jmolSetParameter(key,value) { Jmol.Info[key] = value; } function jmolSetXHTML(id) { Jmol.setXHTML(id); } function jmolSetTranslation(TF) { // n/a } function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) { if (_jmol.initialized) return; _jmol.initialized = true; if(_jmol.jmoljar) { var f = _jmol.jmoljar; if (f.indexOf("/") >= 0) { alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.") var ok = prompt("Do you want to use applet " + f + "? ","yes or no") if (ok == "yes") { codebaseDirectory = f.substring(0, f.lastIndexOf("/")); fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1); } else { _jmolGetJarFilename(fileNameOrUseSignedApplet); alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"'); } } else { fileNameOrUseSignedApplet = f; } } _jmol.codebase = codebaseDirectory; _jmolGetJarFilename(fileNameOrUseSignedApplet); } function jmolSetDocument(doc) { _jmol.currentDocument = doc; } function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) { Jmol.Info.color = boxbgcolor ? boxbgcolor : "black"; } function jmolSetAppletWindow(w) { _jmol.appletWindow = w; } function jmolApplet(size, script, nameSuffix) { return _jmolApplet(size, null, script, nameSuffix); } function jmolAppletInline(size, inlineModel, script, nameSuffix) { return _jmolApplet(size, inlineModel, script, nameSuffix); } //////////////////////////////////////////////////////////////// // Basic controls //////////////////////////////////////////////////////////////// function jmolButton(script, label, id, title) { return Jmol.jmolButton(_jmol.target, script, label, id, title); } function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked, labelHtml, isChecked, id, title) { return Jmol.jmolCheckbox(_jmol.target, scriptWhenChecked, scriptWhenUnchecked, labelHtml, isChecked, id, title) } function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) { return Jmol.jmolRadioGroup(_jmol.target, arrayOfRadioButtons, separatorHtml, groupName, id, title) } function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) { return Jmol.jmolRadio(_jmol.target, script, labelHtml, isChecked, separatorHtml, groupName, id, title) } function jmolLink(script, label, id, title) { return Jmol.jmolLink(_jmol.target, script, label, id, title) } function jmolCommandInput(label, size, id, title) { return Jmol.jmolCommandInput(_jmol.target, label, size, id, title); } function jmolMenu(arrayOfMenuItems, size, id, title) { return Jmol.jmolMenu(_jmol.target, arrayOfMenuItems, size, id, title); } function jmolHtml(html) { return Jmol._documentWrite(html); } function jmolBr() { return Jmol._documentWrite("
"); } //////////////////////////////////////////////////////////////// // advanced scripting functions //////////////////////////////////////////////////////////////// function jmolDebugAlert(enableAlerts) { // n/a } function jmolLoadInline(model, targetSuffix) { return jmolLoadInlineScript(model, null, targetSuffix, false) } function jmolLoadInlineArray(ModelArray, script, targetSuffix) { return jmolLoadInlineScript(ModelArray.join("\n"), script, targetSuffix, false) } function jmolAppendInlineArray(ModelArray, script, targetSuffix) { return jmolLoadInlineScript(ModelArray.join("\n"), script, targetSuffix, true) } function jmolAppendInlineScript(model, script, targetSuffix) { return jmolLoadInlineScript(model, script, targetSuffix, true) } function jmolLoadInlineScript(model, script, targetSuffix, isAppend) { Jmol.script(jmolFindTarget(targetSuffix), "load " + (isAppend ? "APPEND " : "") + "DATA 'mydata'\n" + model.replace(/\"/g,'\\"') + "\nEND 'mydata'\n") } function jmolSetTarget(targetSuffix) { targetSuffix == null || (_jmol.targetSuffix = targetSuffix); return _jmol.target = "jmolApplet" + _jmol.targetSuffix; } function jmolFindTarget(targetSuffix) { return _jmol.applets[jmolSetTarget(targetSuffix)]; } function jmolScript(script, targetSuffix) { Jmol.script(jmolFindTarget(targetSuffix), script) } function jmolCheckBrowser(action, urlOrMessage, nowOrLater) { // unnecessary } //////////////////////////////////////////////////////////////// // Cascading Style Sheet Class support //////////////////////////////////////////////////////////////// function jmolSetAppletCssClass(appletCssClass) { Jmol.setAppletCss(appletCssClass) } function jmolSetButtonCssClass(s) { Jmol.setButtonCss(s) } function jmolSetCheckboxCssClass(s) { Jmol.setCheckboxCss(s) } function jmolSetRadioCssClass(s) { Jmol.setRadioCss(s) } function jmolSetLinkCssClass(s) { Jmol.setLinkCss(s) } function jmolSetMenuCssClass(s) { Jmol.setMenuCss(s) } function jmolSetMemoryMb(nMb) { // n/a } function jmolSetCallback(callbackName,funcName) { //if(!self[funcName])alert(funcName + " is not defined yet in jmolSetCallback") Jmol.Info[callbackName] = funcName //document.title=("jmolSetCallback " + callbackName + "/" + funcName + " must be included in Info definition") } function jmolSetSyncId(n) { alert("jmolSetSyncId " + n + " must be included in Info definition") } function jmolSetLogLevel(n) { Jmol.script(_jmol.target, "set loglevel " + n) } function _jmolGetAppletSize(size, units) { var width, height; if ( (typeof size) == "object" && size != null ) { width = size[0]; height = size[1]; } else { width = height = size; } return [_jmolFixDim(width, units), _jmolFixDim(height, units)]; } function _jmolFixDim(x, units) { var sx = "" + x; return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2]) : sx.indexOf("%") == sx.length-1 ? sx : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%" : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2] : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0] : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1] : x) + (units ? units : "")); } //////////user property/status functions///////// function jmolGetStatus(strStatus,targetSuffix){ return Jmol.getStatus(jmolFindTarget(targetSuffix), strStatus) } function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) { return Jmol.getPropertyAsArray(jmolFindTarget(targetSuffix), sKey, sValue) } function jmolGetPropertyAsString(sKey,sValue,targetSuffix) { return Jmol.getPropertyAsString(jmolFindTarget(targetSuffix), sKey, sValue) } function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) { return Jmol.getPropertyAsJSON(jmolFindTarget(targetSuffix), sKey, sValue) } function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) { return Jmol.getPropertyAsJavaObject(jmolFindTarget(targetSuffix), sKey, sValue) } ///////// synchronous scripting //////// function jmolScriptWait(script, targetSuffix) { return Jmol.scriptWait(jmolFindTarget(targetSuffix), script) } function jmolScriptWaitOutput(script, targetSuffix) { return Jmol.scriptWaitOutput(jmolFindTarget(targetSuffix), script) } function jmolEvaluate(molecularMath, targetSuffix) { return Jmol.evaluate(jmolFindTarget(targetSuffix), molecularMath) } function jmolScriptEcho(script, targetSuffix) { return Jmol.scriptEcho(jmolFindTarget(targetSuffix), script) } function jmolScriptMessage(script, targetSuffix) { return Jmol.scriptMessage(jmolFindTarget(targetSuffix), script) } function jmolScriptWaitAsArray(script, targetSuffix) { return Jmol.scriptWait(jmolFindTarget(targetSuffix), script) } //////////// save/restore orientation ///////////// function jmolSaveOrientation(id, targetSuffix) { return Jmol.saveOrientation(jmolFindTarget(targetSuffix), id) } function jmolRestoreOrientation(id, targetSuffix) { return Jmol.restoreOrientation(jmolFindTarget(targetSuffix), id) } function jmolRestoreOrientationDelayed(id, delay, targetSuffix) { return Jmol.restoreOrientationDelayed(jmolFindTarget(targetSuffix), id, delay) } function jmolResizeApplet(size, targetSuffix) { return Jmol.resizeApplet(jmolFindTarget(targetSuffix), size); } //////////// add parameter ///////////// function jmolAppletAddParam(appletCode,name,value){ alert ("use Info to add a parameter: " + name + "/" + value) }