Subversion Repositories wimsdev

Rev

Rev 2876 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* Jmol 11.9 script library Jmol.js  6:56 AM 1/20/2010 Bob Hanson
  2.  
  3.  checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm
  4.  
  5.     based on:
  6.  *
  7.  * Copyright (C) 2004-2005  Miguel, Jmol Development, www.jmol.org
  8.  *
  9.  * Contact: hansonr@stolaf.edu
  10.  *
  11.  *  This library is free software; you can redistribute it and/or
  12.  *  modify it under the terms of the GNU Lesser General Public
  13.  *  License as published by the Free Software Foundation; either
  14.  *  version 2.1 of the License, or (at your option) any later version.
  15.  *
  16.  *  This library is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19.  *  Lesser General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU Lesser General Public
  22.  *  License along with this library; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  24.  *  02111-1307  USA.
  25.  */
  26.  
  27. // for documentation see www.jmol.org/jslibrary
  28.  
  29. try{if(typeof(_jmol)!="undefined")exit()
  30.  
  31. // place "?NOAPPLET" on your command line to check applet control action with a textarea
  32. // place "?JMOLJAR=xxxxx" to use a specific jar file
  33.  
  34. // bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)
  35. //    angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet
  36. // bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007
  37. // bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007
  38. // bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007
  39. // bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006
  40. // bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006
  41. // bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006
  42. // bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006
  43. // bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.
  44. // bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006
  45. // bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006
  46. // bob hanson -- fix for iframes not available for finding applet
  47. // bob hanson -- added applet fake ?NOAPPLET URL flag
  48. // bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006
  49. //                      used PRIOR to jmolApplet() or jmolAppletInline()
  50. //               added 4th array element in jmolRadioGroup -- title
  51. //               added <span> and id around link, checkbox, radio, menu
  52. //               fixing AJAX loads for MSIE/Opera-Mozilla incompatibility
  53. //            -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar
  54. //               renamed Jmol.js for Jmol 11 distribution
  55. //            -- modified jmolRestoreOrientation() to be immediate, no 1-second delay
  56. // bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006
  57. // bh         -- jmolCommandInput()
  58. // bh         -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues
  59. // bh         -- minor fixes suggested by Angel
  60. // bh         -- adds jmolSetSyncId() and jmolGetSyncId()
  61. // bh 3/2008  -- adds jmolAppendInlineScript() and jmolAppendInlineArray()
  62. // bh 3/2008  -- fixes IE7 bug in relation to jmolLoadInlineArray()
  63. // bh 6/2008  -- adds jmolSetAppletWindow()
  64. // Angel H. 6/2008  -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]
  65. // bh 7/2008  -- code fix "for(i..." not "for(var i..."
  66. // bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)
  67. // bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console
  68.  
  69. // bh 5/2009  -- Support for XHTML using jmolSetXHTML(id)
  70. // ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax
  71. // bh 11/2009 -- care in accessing top.document
  72. // bh 12/2009 -- added jmolSetParameter(name, value)
  73. // bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line
  74. // bh 12/2009 -- overhaul of target checking
  75. // bh 1/2010  -- all _xxxx() methods ALWAYS have complete argument list
  76. // bh 1/2010  -- adds option to run a JavaScript function from any Jmol control.
  77. //               This is accomplished by passing an array rather than a script:
  78. //               jmolHref([myfunc,"my param 1", "my param 2"], "testing")
  79. //               function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}
  80. //               and allows much more flexibility with responding to controls
  81.  
  82. var defaultdir = "."
  83. var defaultjar = "JmolApplet.jar"
  84.  
  85.  
  86. // Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:
  87.  
  88. // JMOLJAR=xxxxx.jar on the URL for this page will override
  89. // the JAR file specified in the jmolInitialize() call.
  90.  
  91. // The idea is that it can be very useful to test a web page with different JAR files
  92. // Or for an expert user to substitute a signed applet for an unsigned one
  93. // so as to use a broader range of models or to create JPEG files, for example.
  94.  
  95. // If the JAR file is not in the current directory (has any sort of "/" in its name)
  96. // then the user is presented with a warning and asked whether it is OK to change Jar files.
  97. // The default action, if the user just presses "OK" is to NOT allow the change.
  98. // The user must type the word "yes" in the prompt box for the change to be approved.
  99.  
  100. // If you don't want people to be able to switch in their own JAR file on your page,
  101. // simply set this next line to read "var allowJMOLJAR = false".
  102.  
  103.  
  104. var undefined; // for IE 5 ... wherein undefined is undefined
  105.  
  106. ////////////////////////////////////////////////////////////////
  107. // Basic Scripting infrastruture
  108. ////////////////////////////////////////////////////////////////
  109.  
  110. function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {
  111.   if (_jmol.initialized)
  112.     return;
  113.   _jmol.initialized = true;
  114.   if(_jmol.jmoljar) {
  115.     var f = _jmol.jmoljar;
  116.     if (f.indexOf("/") >= 0) {
  117.       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.")
  118.       var ok = prompt("Do you want to use applet " + f + "? ","yes or no")
  119.       if (ok == "yes") {
  120.         codebaseDirectory = f.substring(0, f.lastIndexOf("/"));
  121.         fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);
  122.       } else {
  123.         _jmolGetJarFilename(fileNameOrUseSignedApplet);
  124.         alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');
  125.       }
  126.     } else {
  127.       fileNameOrUseSignedApplet = f;
  128.     }
  129.   }
  130.   _jmolSetCodebase(codebaseDirectory);
  131.   _jmolGetJarFilename(fileNameOrUseSignedApplet);
  132.   _jmolOnloadResetForms();
  133. }
  134.  
  135. function jmolSetTranslation(TF) {
  136.   _jmol.params.doTranslate = ''+TF;
  137. }
  138.  
  139. function _jmolGetJarFilename(fileNameOrFlag) {
  140.   _jmol.archivePath =
  141.     (typeof(fileNameOrFlag) == "string"  ? fileNameOrFlag : (fileNameOrFlag ?  "JmolAppletSigned" : "JmolApplet") + "0.jar");
  142. }
  143.  
  144. function jmolSetDocument(doc) {
  145.   _jmol.currentDocument = doc;
  146. }
  147.  
  148. function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
  149.   _jmolInitCheck();
  150.   _jmol.params.boxbgcolor = boxbgcolor;
  151.   if (boxfgcolor)
  152.     _jmol.params.boxfgcolor = boxfgcolor
  153.   else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
  154.     _jmol.params.boxfgcolor = "black";
  155.   else
  156.     _jmol.params.boxfgcolor = "white";
  157.   if (progresscolor)
  158.     _jmol.params.progresscolor = progresscolor;
  159.   if (_jmol.debugAlert)
  160.     alert(" boxbgcolor=" + _jmol.params.boxbgcolor +
  161.           " boxfgcolor=" + _jmol.params.boxfgcolor +
  162.           " progresscolor=" + _jmol.params.progresscolor);
  163. }
  164.  
  165. function jmolSetAppletWindow(w) {
  166.   _jmol.appletWindow = w;
  167. }
  168.  
  169. function jmolApplet(size, script, nameSuffix) {
  170.   _jmolInitCheck();
  171.   return _jmolApplet(size, null, script, nameSuffix);
  172. }
  173.  
  174. ////////////////////////////////////////////////////////////////
  175. // Basic controls
  176. ////////////////////////////////////////////////////////////////
  177.  
  178. // undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)
  179.  
  180. function jmolButton(script, label, id, title) {
  181.   _jmolInitCheck();
  182.   id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);
  183.   label != undefined && label != null || (label = script.substring(0, 32));
  184.   ++_jmol.buttonCount;
  185.   var scriptIndex = _jmolAddScript(script);
  186.   var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +
  187.           "' value='" + label +
  188.           "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +
  189.           ")' onmouseover='_jmolMouseOver(" + scriptIndex +
  190.           ");return true' onmouseout='_jmolMouseOut()' " +
  191.           _jmol.buttonCssText + " /></span>";
  192.   if (_jmol.debugAlert)
  193.     alert(t);
  194.   return _jmolDocumentWrite(t);
  195. }
  196.  
  197. function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
  198.                       labelHtml, isChecked, id, title) {
  199.   _jmolInitCheck();
  200.   id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);
  201.   ++_jmol.checkboxCount;
  202.   if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
  203.       scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
  204.     alert("jmolCheckbox requires two scripts");
  205.     return;
  206.   }
  207.   if (labelHtml == undefined || labelHtml == null) {
  208.     alert("jmolCheckbox requires a label");
  209.     return;
  210.   }
  211.   var indexChecked = _jmolAddScript(scriptWhenChecked);
  212.   var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
  213.   var eospan = "</span>"
  214.   var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +
  215.           "' onclick='_jmolCbClick(this," +
  216.           indexChecked + "," + indexUnchecked + _jmol.targetText +
  217.           ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +
  218.           indexUnchecked +
  219.           ");return true' onmouseout='_jmolMouseOut()' " +
  220.           (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />"
  221.   if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
  222.         t += eospan
  223.         eospan = "";
  224.   }
  225.   t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;
  226.   if (_jmol.debugAlert)
  227.     alert(t);
  228.   return _jmolDocumentWrite(t);
  229. }
  230.  
  231. function jmolStartNewRadioGroup() {
  232.   ++_jmol.radioGroupCount;
  233. }
  234.  
  235. function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {
  236.   /*
  237.  
  238.     array: [radio1,radio2,radio3...]
  239.     where radioN = ["script","label",isSelected,"id","title"]
  240.  
  241.   */
  242.  
  243.   _jmolInitCheck();
  244.   var type = typeof arrayOfRadioButtons;
  245.   if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
  246.     alert("invalid arrayOfRadioButtons");
  247.     return;
  248.   }
  249.   separatorHtml != undefined && separatorHtml != null || (separatorHtml = "&nbsp; ");
  250.   var len = arrayOfRadioButtons.length;
  251.   jmolStartNewRadioGroup();
  252.   groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
  253.   var t = "<span id='"+(id ? id : groupName)+"'>";
  254.   for (var i = 0; i < len; ++i) {
  255.     if (i == len - 1)
  256.       separatorHtml = "";
  257.     var radio = arrayOfRadioButtons[i];
  258.     type = typeof radio;
  259.     if (type == "object") {
  260.       t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);
  261.     } else {
  262.       t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);
  263.     }
  264.   }
  265.   t+="</span>"
  266.   if (_jmol.debugAlert)
  267.     alert(t);
  268.   return _jmolDocumentWrite(t);
  269. }
  270.  
  271.  
  272. function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
  273.   _jmolInitCheck();
  274.   if (_jmol.radioGroupCount == 0)
  275.     ++_jmol.radioGroupCount;
  276.   var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);
  277.   if (_jmol.debugAlert)
  278.     alert(t);
  279.   return _jmolDocumentWrite(t);
  280. }
  281.  
  282. function jmolLink(script, label, id, title) {
  283.   _jmolInitCheck();
  284.   id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);
  285.   label != undefined && label != null || (label = script.substring(0, 32));
  286.   ++_jmol.linkCount;
  287.   var scriptIndex = _jmolAddScript(script);
  288.   var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id +
  289.           "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +
  290.           ");return true;' onmouseout='_jmolMouseOut()' " +
  291.           _jmol.linkCssText + ">" + label + "</a></span>";
  292.   if (_jmol.debugAlert)
  293.     alert(t);
  294.   return _jmolDocumentWrite(t);
  295. }
  296.  
  297. function jmolCommandInput(label, size, id, title) {
  298.   _jmolInitCheck();
  299.   id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);
  300.   label != undefined && label != null || (label = "Execute");
  301.   size != undefined && !isNaN(size) || (size = 60);
  302.   ++_jmol.cmdCount;
  303.   var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id +
  304.           "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";
  305.   if (_jmol.debugAlert)
  306.     alert(t);
  307.   return _jmolDocumentWrite(t);
  308. }
  309.  
  310. function _jmolCommandKeyPress(e, id, target) {
  311.         var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);
  312.         if (keycode == 13) {
  313.                 var inputBox = document.getElementById(id)
  314.                 _jmolScriptExecute(inputBox, inputBox.value, target)
  315.         }
  316. }
  317.  
  318. function _jmolScriptExecute(element,script,target) {
  319.         if (typeof(script) == "object")
  320.                 script[0](element, script, target)
  321.         else
  322.                 jmolScript(script, target)
  323. }
  324.  
  325. function jmolMenu(arrayOfMenuItems, size, id, title) {
  326.   _jmolInitCheck();
  327.   id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);
  328.   ++_jmol.menuCount;
  329.   var type = typeof arrayOfMenuItems;
  330.   if (type != null && type == "object" && arrayOfMenuItems.length) {
  331.     var len = arrayOfMenuItems.length;
  332.     if (typeof size != "number" || size == 1)
  333.       size = null;
  334.     else if (size < 0)
  335.       size = len;
  336.     var sizeText = size ? " size='" + size + "' " : "";
  337.     var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +
  338.             "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +
  339.             sizeText + _jmol.menuCssText + ">";
  340.     for (var i = 0; i < len; ++i) {
  341.       var menuItem = arrayOfMenuItems[i];
  342.       type = typeof menuItem;
  343.       var script, text;
  344.       var isSelected = undefined;
  345.       if (type == "object" && menuItem != null) {
  346.         script = menuItem[0];
  347.         text = menuItem[1];
  348.         isSelected = menuItem[2];
  349.       } else {
  350.         script = text = menuItem;
  351.       }
  352.       text != undefined && text != null || (text = script);            
  353.       if (script=="#optgroup") {
  354.         t += "<optgroup label='" + text + "'>";  
  355.           } else if (script=="#optgroupEnd") {
  356.         t += "</optgroup>";      
  357.           } else {             
  358.         var scriptIndex = _jmolAddScript(script);
  359.         var selectedText = isSelected ? "' selected='true'>" : "'>";
  360.         t += "<option value='" + scriptIndex + selectedText + text + "</option>";
  361.       }
  362.     }
  363.     t += "</select></span>";
  364.     if (_jmol.debugAlert)
  365.       alert(t);
  366.     return _jmolDocumentWrite(t);
  367.   }
  368. }
  369.  
  370. function jmolHtml(html) {
  371.   return _jmolDocumentWrite(html);
  372. }
  373.  
  374. function jmolBr() {
  375.   return _jmolDocumentWrite("<br />");
  376. }
  377.  
  378. ////////////////////////////////////////////////////////////////
  379. // advanced scripting functions
  380. ////////////////////////////////////////////////////////////////
  381.  
  382. function jmolDebugAlert(enableAlerts) {
  383.   _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
  384. }
  385.  
  386. function jmolAppletInline(size, inlineModel, script, nameSuffix) {
  387.   _jmolInitCheck();
  388.   return _jmolApplet(size, _jmolSterilizeInline(inlineModel),
  389.                      script, nameSuffix);
  390. }
  391.  
  392. function jmolSetTarget(targetSuffix) {
  393.   _jmol.targetSuffix = targetSuffix;
  394.   _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";
  395. }
  396.  
  397. function jmolScript(script, targetSuffix) {
  398.   if (script) {
  399.     _jmolCheckBrowser();
  400.     if (targetSuffix == "all") {
  401.       with (_jmol) {
  402.         for (var i = 0; i < appletSuffixes.length; ++i) {
  403.           var applet = _jmolGetApplet(appletSuffixes[i]);
  404.           if (applet) applet.script(script);
  405.         }
  406.       }
  407.     } else {
  408.       var applet=_jmolGetApplet(targetSuffix);
  409.       if (applet) applet.script(script);
  410.     }
  411.   }
  412. }
  413.  
  414. function jmolLoadInline(model, targetSuffix) {
  415.   if (!model)return "ERROR: NO MODEL"
  416.   var applet=_jmolGetApplet(targetSuffix);
  417.   if (!applet)return "ERROR: NO APPLET"
  418.   if (typeof(model) == "string")
  419.     return applet.loadInlineString(model, "", false);
  420.   else
  421.     return applet.loadInlineArray(model, "", false);
  422. }
  423.  
  424.  
  425. function jmolLoadInlineScript(model, script, targetSuffix) {
  426.   if (!model)return "ERROR: NO MODEL"
  427.   var applet=_jmolGetApplet(targetSuffix);
  428.   if (!applet)return "ERROR: NO APPLET"
  429.   return applet.loadInlineString(model, script, false);
  430. }
  431.  
  432.  
  433. function jmolLoadInlineArray(ModelArray, script, targetSuffix) {
  434.   if (!model)return "ERROR: NO MODEL"
  435.   script || (script="")
  436.   var applet=_jmolGetApplet(targetSuffix);
  437.   if (!applet)return "ERROR: NO APPLET"
  438.   try {
  439.     return applet.loadInlineArray(ModelArray, script, false);
  440.   } catch (err) {
  441.     //IE 7 bug
  442.     return applet.loadInlineString(ModelArray.join("\n"), script, false);
  443.   }
  444. }
  445.  
  446. function jmolAppendInlineArray(ModelArray, script, targetSuffix) {
  447.   if (!model)return "ERROR: NO MODEL"
  448.   script || (script="")
  449.   var applet=_jmolGetApplet(targetSuffix);
  450.   if (!applet)return "ERROR: NO APPLET"
  451.   try {
  452.     return applet.loadInlineArray(ModelArray, script, true);
  453.   } catch (err) {
  454.     //IE 7 bug
  455.     return applet.loadInlineString(ModelArray.join("\n"), script, true);
  456.   }
  457. }
  458.  
  459. function jmolAppendInlineScript(model, script, targetSuffix) {
  460.   if (!model)return "ERROR: NO MODEL"
  461.   var applet=_jmolGetApplet(targetSuffix);
  462.   if (!applet)return "ERROR: NO APPLET"
  463.   return applet.loadInlineString(model, script, true);
  464. }
  465.  
  466. function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
  467.   if (typeof action == "string") {
  468.     action = action.toLowerCase();
  469.     action == "alert" || action == "redirect" || action == "popup" || (action = null);
  470.   }
  471.   if (typeof action != "string")
  472.     alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
  473.           "action must be 'alert', 'redirect', or 'popup'");
  474.   else {
  475.     if (typeof urlOrMessage != "string")
  476.       alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
  477.             "urlOrMessage must be a string");
  478.     else {
  479.       _jmol.checkBrowserAction = action;
  480.       _jmol.checkBrowserUrlOrMessage = urlOrMessage;
  481.     }
  482.   }
  483.   if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
  484.     _jmolCheckBrowser();
  485. }
  486.  
  487. ////////////////////////////////////////////////////////////////
  488. // Cascading Style Sheet Class support
  489. ////////////////////////////////////////////////////////////////
  490.  
  491. function jmolSetAppletCssClass(appletCssClass) {
  492.   if (_jmol.hasGetElementById) {
  493.     _jmol.appletCssClass = appletCssClass;
  494.     _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
  495.   }
  496. }
  497.  
  498. function jmolSetButtonCssClass(buttonCssClass) {
  499.   if (_jmol.hasGetElementById) {
  500.     _jmol.buttonCssClass = buttonCssClass;
  501.     _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
  502.   }
  503. }
  504.  
  505. function jmolSetCheckboxCssClass(checkboxCssClass) {
  506.   if (_jmol.hasGetElementById) {
  507.     _jmol.checkboxCssClass = checkboxCssClass;
  508.     _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
  509.   }
  510. }
  511.  
  512. function jmolSetRadioCssClass(radioCssClass) {
  513.   if (_jmol.hasGetElementById) {
  514.     _jmol.radioCssClass = radioCssClass;
  515.     _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
  516.   }
  517. }
  518.  
  519. function jmolSetLinkCssClass(linkCssClass) {
  520.   if (_jmol.hasGetElementById) {
  521.     _jmol.linkCssClass = linkCssClass;
  522.     _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
  523.   }
  524. }
  525.  
  526. function jmolSetMenuCssClass(menuCssClass) {
  527.   if (_jmol.hasGetElementById) {
  528.     _jmol.menuCssClass = menuCssClass;
  529.     _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
  530.   }
  531. }
  532.  
  533. ////////////////////////////////////////////////////////////////
  534. // functions for INTERNAL USE ONLY which are subject to change
  535. // use at your own risk ... you have been WARNED!
  536. ////////////////////////////////////////////////////////////////
  537. var _jmol = {
  538.   currentDocument: document,
  539.  
  540.   debugAlert: false,
  541.  
  542.   codebase: "",
  543.   modelbase: ".",
  544.  
  545.   appletCount: 0,
  546.   appletSuffixes: [],
  547.   appletWindow: null,
  548.   allowedJmolSize: [25, 2048, 300],   // min, max, default (pixels)
  549.           /*  By setting the _jmol.allowedJmolSize[] variable in the webpage
  550.               before calling jmolApplet(), limits for applet size can be overriden.
  551.                     2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)
  552.           */  
  553.   buttonCount: 0,
  554.   checkboxCount: 0,
  555.   linkCount: 0,
  556.   cmdCount: 0,
  557.   menuCount: 0,
  558.   radioCount: 0,
  559.   radioGroupCount: 0,
  560.  
  561.   appletCssClass: null,
  562.   appletCssText: "",
  563.   buttonCssClass: null,
  564.   buttonCssText: "",
  565.   checkboxCssClass: null,
  566.   checkboxCssText: "",
  567.   radioCssClass: null,
  568.   radioCssText: "",
  569.   linkCssClass: null,
  570.   linkCssText: "",
  571.   menuCssClass: null,
  572.   menuCssText: "",
  573.  
  574.   targetSuffix: 0,
  575.   targetText: ",0",
  576.   scripts: [""],
  577.   params: {
  578.         syncId: ("" + Math.random()).substring(3),
  579.         progressbar: "true",
  580.         progresscolor: "blue",
  581.         boxbgcolor: "black",
  582.         boxfgcolor: "white",
  583.         boxmessage: "Downloading JmolApplet ..."
  584.   },
  585.   ua: navigator.userAgent.toLowerCase(),
  586.   uaVersion: parseFloat(navigator.appVersion),
  587.  
  588.   os: "unknown",
  589.   browser: "unknown",
  590.   browserVersion: 0,
  591.   hasGetElementById: !!document.getElementById,
  592.   isJavaEnabled: navigator.javaEnabled(),
  593.   isNetscape47Win: false,
  594.   isIEWin: false,
  595.   useIEObject: false,
  596.   useHtml4Object: false,
  597.  
  598.   windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
  599.   windowsCabUrl:
  600.    "http://java.sun.com/update/1.5.0/jinstall-1_5_0_05-windows-i586.cab",
  601.  
  602.   isBrowserCompliant: false,
  603.   isJavaCompliant: false,
  604.   isFullyCompliant: false,
  605.  
  606.   initialized: false,
  607.   initChecked: false,
  608.  
  609.   browserChecked: false,
  610.   checkBrowserAction: "alert",
  611.   checkBrowserUrlOrMessage: null,
  612.  
  613.   archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar
  614.  
  615.   previousOnloadHandler: null,
  616.  
  617.   jmoljar: null,  
  618.   useNoApplet: false,
  619.  
  620.   ready: {}
  621. }
  622.  
  623. with (_jmol) {
  624.   function _jmolTestUA(candidate) {
  625.     var ua = _jmol.ua;
  626.     var index = ua.indexOf(candidate);
  627.     if (index < 0)
  628.       return false;
  629.     _jmol.browser = candidate;
  630.     _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));
  631.     return true;
  632.   }
  633.  
  634.   function _jmolTestOS(candidate) {
  635.     if (_jmol.ua.indexOf(candidate) < 0)
  636.       return false;
  637.     _jmol.os = candidate;
  638.     return true;
  639.   }
  640.  
  641.   _jmolTestUA("konqueror") ||
  642.   _jmolTestUA("safari") ||
  643.   _jmolTestUA("omniweb") ||
  644.   _jmolTestUA("opera") ||
  645.   _jmolTestUA("webtv") ||
  646.   _jmolTestUA("icab") ||
  647.   _jmolTestUA("msie") ||
  648.   (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla"));
  649.  
  650.   _jmolTestOS("linux") ||
  651.   _jmolTestOS("unix") ||
  652.   _jmolTestOS("mac") ||
  653.   _jmolTestOS("win");
  654.  
  655.   isNetscape47Win = (os == "win" && browser == "mozilla" &&
  656.                      browserVersion >= 4.78 && browserVersion <= 4.8);
  657.  
  658.   if (os == "win") {
  659.     isBrowserCompliant = hasGetElementById;
  660.   } else if (os == "mac") { // mac is the problem child :-(
  661.     if (browser == "mozilla" && browserVersion >= 5) {
  662.       // miguel 2004 11 17
  663.       // checking the plugins array does not work because
  664.       // Netscape 7.2 OS X still has Java 1.3.1 listed even though
  665.       // javaplugin.sf.net is installed to upgrade to 1.4.2
  666.       eval("try {var v = java.lang.System.getProperty('java.version');" +
  667.            " _jmol.isBrowserCompliant = v >= '1.4.2';" +
  668.            " } catch (e) { }");
  669.     } else if (browser == "opera" && browserVersion <= 7.54) {
  670.       isBrowserCompliant = false;
  671.     } else {
  672.       isBrowserCompliant = hasGetElementById &&
  673.         !((browser == "msie") ||
  674.           (browser == "safari" && browserVersion < 125.12));
  675.     }
  676.   } else if (os == "linux" || os == "unix") {
  677.     if (browser == "konqueror" && browserVersion <= 3.3)
  678.       isBrowserCompliant = false;
  679.     else
  680.       isBrowserCompliant = hasGetElementById;
  681.   } else { // other OS
  682.     isBrowserCompliant = hasGetElementById;
  683.   }
  684.  
  685.   // possibly more checks in the future for this
  686.   isJavaCompliant = isJavaEnabled;
  687.  
  688.   isFullyCompliant = isBrowserCompliant && isJavaCompliant;
  689.  
  690.   // IE5.5 works just fine ... but let's push them to Sun Java
  691.   isIEWin = (os == "win" && browser == "msie" && browserVersion >= 5.5);
  692.   useIEObject = isIEWin;
  693.   useHtml4Object =
  694.    (os != "mac" && browser == "mozilla" && browserVersion >= 5) ||
  695.    (os == "win" && browser == "opera" && browserVersion >= 8) ||
  696.    (os == "mac" && browser == "safari" && browserVersion >= 412.2);
  697.  try {
  698.   if (top.location.search.indexOf("JMOLJAR=")>=0)
  699.     jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];
  700.  } catch(e) {
  701.   // can't access top.location
  702.  }
  703.  try {
  704.   useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);
  705.  } catch(e) {
  706.   // can't access top.document
  707.  }
  708. }
  709.  
  710. function jmolSetParameter(name,value) {
  711.   _jmol.params[name] = value
  712. }
  713.  
  714. function jmolSetCallback(callbackName,funcName) {
  715.   _jmol.params[callbackName] = funcName
  716. }
  717.  
  718.  try {
  719. // note this is done FIRST, so it cannot override a setting done by the developer
  720.   if (top.location.search.indexOf("PARAMS=")>=0) {
  721.     var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");
  722.     for (var i = 0; i < pars.length; i++) {
  723.       var p = pars[i].split(":");
  724.       jmolSetParameter(p[0],p[1]);
  725.     }
  726.   }
  727.  } catch(e) {
  728.   // can't access top.location
  729.  }
  730.  
  731. function jmolSetSyncId(n) {
  732.   return _jmol.params["syncId"] = n
  733. }
  734.  
  735. function jmolGetSyncId() {
  736.   return _jmol.params["syncId"]
  737. }
  738.  
  739. function jmolSetLogLevel(n) {
  740.   _jmol.params.logLevel = ''+n;
  741. }
  742.  
  743.         /*  AngelH, mar2007:
  744.                 By (re)setting these variables in the webpage before calling jmolApplet(),
  745.                 a custom message can be provided (e.g. localized for user's language) when no Java is installed.
  746.         */
  747. if (noJavaMsg==undefined) var noJavaMsg =
  748.         "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +
  749.         "Check the warning message from your browser and/or enable Java applets in<br />\n" +
  750.         "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";
  751. if (noJavaMsg2==undefined) var noJavaMsg2 =
  752.         "You do not have the<br />\n" +
  753.         "Java Runtime Environment<br />\n" +
  754.         "installed for applet support.<br />\n" +
  755.         "Visit <a href='http://www.java.com'>www.java.com</a>";
  756. function _jmolApplet(size, inlineModel, script, nameSuffix) {
  757.         /*  AngelH, mar2007
  758.                 Fixed percent / pixel business, to avoid browser errors:
  759.                 put "px" where needed, avoid where not.
  760.  
  761.             Bob Hanson, 1/2010
  762.                 Fixed inline escape changing returns to |              
  763.         */
  764.   with (_jmol) {
  765.     nameSuffix == undefined && (nameSuffix = appletCount);
  766.     appletSuffixes.push(nameSuffix);
  767.     ++appletCount;
  768.     script || (script = "select *");
  769.     var sz = _jmolGetAppletSize(size);
  770.     var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";
  771.     var tHeader, tFooter;
  772.     codebase || jmolInitialize(".");
  773.     if (useIEObject || useHtml4Object) {
  774.       params.name = 'jmolApplet' + nameSuffix;
  775.       params.archive = archivePath;
  776.       params.mayscript = 'true';
  777.       params.codebase = codebase;
  778.     }
  779.     if (useIEObject) { // use MSFT IE6 object tag with .cab file reference
  780.       winCodebase = (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "");
  781.       params.code = 'JmolApplet';
  782.       tHeader =
  783.         "<object name='jmolApplet" + nameSuffix +
  784.         "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
  785.         " classid='" + windowsClassId + "'\n" + winCodebase + widthAndHeight + ">\n";
  786.       tFooter = "</object>";
  787.     } else if (useHtml4Object) { // use HTML4 object tag
  788.       tHeader =
  789.         "<object name='jmolApplet" + nameSuffix +
  790.         "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
  791.         " classid='java:JmolApplet'\n" +
  792.         " type='application/x-java-applet'\n" +
  793.         widthAndHeight + ">\n";
  794.       tFooter = "</object>";
  795.     } else { // use applet tag
  796.       tHeader =
  797.         "<applet name='jmolApplet" + nameSuffix +
  798.         "' id='jmolApplet" + nameSuffix +
  799.         "' " + appletCssText +
  800.         " code='JmolApplet'" +
  801.         " archive='" + archivePath + "' codebase='" + codebase + "'\n" +
  802.                 widthAndHeight +
  803.         " mayscript='true'>\n";
  804.       tFooter = "</applet>";
  805.     }
  806.     var visitJava;
  807.     if (isIEWin || useHtml4Object) {
  808.                 var szX = "width:" + sz[0]
  809.                 if ( szX.indexOf("%")==-1 ) szX+="px"
  810.                 var szY = "height:" + sz[1]
  811.                 if ( szY.indexOf("%")==-1 ) szY+="px"
  812.       visitJava =
  813.         "<p style='background-color:yellow; color:black; " +
  814.                 szX + ";" + szY + ";" +
  815.         // why doesn't this vertical-align work?
  816.         "text-align:center;vertical-align:middle;'>\n" +
  817.                 noJavaMsg +
  818.         "</p>";
  819.     } else {
  820.       visitJava =
  821.         "<table bgcolor='yellow'><tr>" +
  822.         "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +
  823.                 noJavaMsg2 +
  824.         "</font></td></tr></table>";
  825.     }
  826.     params.loadInline = (inlineModel ? inlineModel : "");
  827.     params.script = (script ? _jmolSterilizeScript(script) : "");
  828.     var t = tHeader + _jmolParams() + visitJava + tFooter;
  829.     jmolSetTarget(nameSuffix);
  830.     ready["jmolApplet" + nameSuffix] = false;
  831.     if (_jmol.debugAlert)
  832.       alert(t);
  833.     return _jmolDocumentWrite(t);
  834.   }
  835. }
  836.  
  837. function _jmolParams() {
  838.  var t = "";
  839.  for (var i in _jmol.params)
  840.         if(_jmol.params[i]!="")
  841.                  t+="  <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";
  842.  return t
  843. }
  844.  
  845. function _jmolInitCheck() {
  846.   if (_jmol.initChecked)
  847.     return;
  848.   _jmol.initChecked = true;
  849.   jmolInitialize(defaultdir, defaultjar)
  850. }
  851.  
  852. function _jmolCheckBrowser() {
  853.   with (_jmol) {
  854.     if (browserChecked)
  855.       return;
  856.     browserChecked = true;
  857.  
  858.     if (isFullyCompliant)
  859.       return true;
  860.  
  861.     if (checkBrowserAction == "redirect")
  862.       location.href = checkBrowserUrlOrMessage;
  863.     else if (checkBrowserAction == "popup")
  864.       _jmolPopup(checkBrowserUrlOrMessage);
  865.     else {
  866.       var msg = checkBrowserUrlOrMessage;
  867.       if (msg == null)
  868.         msg = "Your web browser is not fully compatible with Jmol\n\n" +
  869.               "browser: " + browser +
  870.               "   version: " + browserVersion +
  871.               "   os: " + os +
  872.               "   isBrowserCompliant: " + isBrowserCompliant +
  873.               "   isJavaCompliant: " + isJavaCompliant +
  874.               "\n\n" + ua;
  875.       alert(msg);
  876.     }
  877.   }
  878.   return false;
  879. }
  880.  
  881. function jmolSetXHTML(id) {
  882.         _jmol.isXHTML = true
  883.         _jmol.XhtmlElement = null
  884.         _jmol.XhtmlAppendChild = false
  885.         if (id){
  886.                 _jmol.XhtmlElement = document.getElementById(id)
  887.                 _jmol.XhtmlAppendChild = true
  888.         }
  889. }
  890.  
  891. function _jmolDocumentWrite(text) {
  892.         if (_jmol.currentDocument) {
  893.                 if (_jmol.isXHTML && !_jmol.XhtmlElement) {
  894.                         var s = document.getElementsByTagName("script")
  895.                         _jmol.XhtmlElement = s.item(s.length - 1)
  896.                         _jmol.XhtmlAppendChild = false
  897.                 }
  898.                 if (_jmol.XhtmlElement) {
  899.                         _jmolDomDocumentWrite(text)
  900.                 } else {
  901.                         _jmol.currentDocument.write(text);
  902.                 }
  903.         }
  904.         return text;
  905. }
  906.  
  907. function _jmolDomDocumentWrite(data) {
  908.         var pt = 0
  909.         var Ptr = []
  910.         Ptr[0] = 0
  911.         while (Ptr[0] < data.length) {
  912.                 var child = _jmolGetDomElement(data, Ptr)
  913.                 if (!child)break
  914.                 if (_jmol.XhtmlAppendChild)
  915.                         _jmol.XhtmlElement.appendChild(child)
  916.                 else
  917.                         _jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement);
  918.         }
  919. }
  920. function _jmolGetDomElement(data, Ptr, closetag, lvel) {
  921.         var e = document.createElement("span")
  922.         e.innerHTML = data
  923.         Ptr[0] = data.length
  924.         return e
  925.  
  926. //unnecessary?
  927.  
  928.         closetag || (closetag = "")
  929.         lvel || (lvel = 0)
  930.         var pt0 = Ptr[0]
  931.         var pt = pt0
  932.         while (pt < data.length && data.charAt(pt) != "<") pt++
  933.         if (pt != pt0) {
  934.                 var text = data.substring(pt0, pt)
  935.                 Ptr[0] = pt
  936.                 return document.createTextNode(text)
  937.         }      
  938.         pt0 = ++pt
  939.         var ch
  940.         while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++
  941.         var tagname = data.substring(pt0, pt)
  942.         var e = (tagname == closetag  || tagname == "/" ? ""
  943.                 : document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)
  944.                 : document.createElement(tagname));
  945.         if (ch == ">") {
  946.                 Ptr[0] = ++pt
  947.                 return e
  948.         }
  949.         while (pt < data.length && (ch = data.charAt(pt)) != ">") {
  950.                 while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
  951.                 pt0 = pt
  952.                 while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++
  953.                 var attrname = data.substring(pt0, pt).toLowerCase()
  954.                 if (attrname && ch != "=")
  955.                         e.setAttribute(attrname, "true")
  956.                 while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
  957.                 if (ch == "/") {
  958.                         Ptr[0] = pt + 2
  959.                         return e
  960.                 } else if (ch == "=") {
  961.                         var quote = data.charAt(++pt)
  962.                         pt0 = ++pt
  963.                         while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++
  964.                         var attrvalue = data.substring(pt0, pt)
  965.                         e.setAttribute(attrname, attrvalue)
  966.                         pt++
  967.                 }
  968.         }
  969.         Ptr[0] = ++pt
  970.         while (Ptr[0] < data.length) {
  971.                 var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)
  972.                 if (!child)break
  973.                 e.appendChild(child)
  974.         }
  975.         return e
  976. }
  977.  
  978. function _jmolPopup(url) {
  979.   var popup = window.open(url, "JmolPopup",
  980.                           "left=150,top=150,height=400,width=600," +
  981.                           "directories=yes,location=yes,menubar=yes," +
  982.                           "toolbar=yes," +
  983.                           "resizable=yes,scrollbars=yes,status=yes");
  984.   if (popup.focus)
  985.     poup.focus();
  986. }
  987.  
  988. function _jmolReadyCallback(name) {
  989.   if (_jmol.debugAlert)
  990.     alert(name + " is ready");
  991.   _jmol.ready["" + name] = true;
  992. }
  993.  
  994. function _jmolSterilizeScript(script) {
  995.   script = script.replace(/'/g, "&#39;");
  996.   if (_jmol.debugAlert)
  997.     alert("script:\n" + script);
  998.   return script;
  999. }
  1000.  
  1001. function _jmolSterilizeInline(model) {
  1002.   model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "&#39;");
  1003.   if (_jmol.debugAlert)
  1004.     alert("inline model:\n" + model);
  1005.   return model;
  1006. }
  1007.  
  1008. function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
  1009.   ++_jmol.radioCount;
  1010.   groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
  1011.   if (!script)
  1012.     return "";
  1013.   labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));
  1014.   separatorHtml || (separatorHtml = "")
  1015.   var scriptIndex = _jmolAddScript(script);
  1016.   var eospan = "</span>"
  1017.   var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='"
  1018.         + groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +
  1019.          scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +
  1020.          scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +
  1021.          (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"
  1022.   if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
  1023.         t += eospan
  1024.         eospan = "";
  1025.   }
  1026.   t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;
  1027.  
  1028.   return t;
  1029. }
  1030.  
  1031. function _jmolFindApplet(target) {
  1032.   // first look for the target in the current window
  1033.   var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);
  1034.   // THEN look for the target in child frames
  1035.   if (applet == undefined)
  1036.     applet = _jmolSearchFrames(window, target);
  1037.   // FINALLY look for the target in sibling frames
  1038.   if (applet == undefined)
  1039.     applet = _jmolSearchFrames(top, target); // look starting in top frame
  1040.   return applet;
  1041. }
  1042.  
  1043. function _jmolGetApplet(targetSuffix){
  1044.  var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
  1045.  var applet = _jmolFindApplet(target);
  1046.  if (applet) return applet
  1047.  _jmol.alerted || alert("could not find applet " + target);
  1048.  _jmol.alerted = true;
  1049.  return null
  1050. }
  1051.  
  1052. function _jmolSearchFrames(win, target) {
  1053.   var applet;
  1054.   var frames = win.frames;
  1055.   if (frames && frames.length) { // look in all the frames below this window
  1056.    try{
  1057.     for (var i = 0; i < frames.length; ++i) {
  1058.       applet = _jmolSearchFrames(frames[i], target);
  1059.       if (applet)
  1060.         return applet;
  1061.     }
  1062.    }catch(e) {
  1063.         if (_jmol.debugAlert)
  1064.                 alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()")
  1065.    }
  1066.   }
  1067.   return applet = _jmolFindAppletInWindow(win, target)
  1068. }
  1069.  
  1070. function _jmolFindAppletInWindow(win, target) {
  1071.     var doc = win.document;
  1072.     // getElementById fails on MacOSX Safari & Mozilla 
  1073.     if (_jmol.useHtml4Object || _jmol.useIEObject)
  1074.       return doc.getElementById(target);
  1075.     else if (doc.applets)
  1076.       return doc.applets[target];
  1077.     else
  1078.       return doc[target];
  1079. }
  1080.  
  1081. function _jmolAddScript(script) {
  1082.   if (!script)
  1083.     return 0;
  1084.   var index = _jmol.scripts.length;
  1085.   _jmol.scripts[index] = script;
  1086.   return index;
  1087. }
  1088.  
  1089. function _jmolClick(elementClicked, scriptIndex, targetSuffix) {
  1090.   _jmol.element = elementClicked;
  1091.   _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);
  1092. }
  1093.  
  1094. function _jmolMenuSelected(menuObject, targetSuffix) {
  1095.   var scriptIndex = menuObject.value;
  1096.   if (scriptIndex != undefined) {
  1097.     _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);
  1098.     return;
  1099.   }
  1100.   var len = menuObject.length;
  1101.   if (typeof len == "number") {
  1102.     for (var i = 0; i < len; ++i) {
  1103.       if (menuObject[i].selected) {
  1104.         _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);
  1105.         return;
  1106.       }
  1107.     }
  1108.   }
  1109.   alert("?Que? menu selected bug #8734");
  1110. }
  1111.  
  1112.  
  1113. _jmol.checkboxMasters = {};
  1114. _jmol.checkboxItems = {};
  1115.  
  1116. function jmolSetCheckboxGroup(chkMaster,chkBox) {
  1117.         var id = chkMaster;
  1118.         if(typeof(id)=="number")id = "jmolCheckbox" + id;
  1119.         chkMaster = document.getElementById(id);
  1120.         if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);
  1121.         var m = _jmol.checkboxMasters[id] = {};
  1122.         m.chkMaster = chkMaster;
  1123.         m.chkGroup = {};
  1124.         for (var i = 1; i < arguments.length; i++){
  1125.                 var id = arguments[i];
  1126.                 if(typeof(id)=="number")id = "jmolCheckbox" + id;
  1127.                 checkboxItem = document.getElementById(id);
  1128.                 if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);
  1129.                 m.chkGroup[id] = checkboxItem;
  1130.                 _jmol.checkboxItems[id] = m;
  1131.         }
  1132. }
  1133.  
  1134. function _jmolNotifyMaster(m){
  1135.         //called when a group item is checked
  1136.         var allOn = true;
  1137.         var allOff = true;
  1138.         for (var chkBox in m.chkGroup){
  1139.                 if(m.chkGroup[chkBox].checked)
  1140.                         allOff = false;
  1141.                 else
  1142.                         allOn = false;
  1143.         }
  1144.         if (allOn)m.chkMaster.checked = true;  
  1145.         if (allOff)m.chkMaster.checked = false;
  1146.         if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])
  1147.                 _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])
  1148. }
  1149.  
  1150. function _jmolNotifyGroup(m, isOn){
  1151.         //called when a master item is checked
  1152.         for (var chkBox in m.chkGroup){
  1153.                 var item = m.chkGroup[chkBox]
  1154.                 item.checked = isOn;
  1155.                 if (_jmol.checkboxMasters[item.id])
  1156.                         _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)
  1157.         }
  1158. }
  1159.  
  1160. function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
  1161.   _jmol.control = ckbox
  1162.   _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
  1163.   if(_jmol.checkboxMasters[ckbox.id])
  1164.         _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)
  1165.   if(_jmol.checkboxItems[ckbox.id])
  1166.         _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])
  1167. }
  1168.  
  1169. function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
  1170.   window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
  1171. }
  1172.  
  1173. function _jmolMouseOver(scriptIndex) {
  1174.   window.status = _jmol.scripts[scriptIndex];
  1175. }
  1176.  
  1177. function _jmolMouseOut() {
  1178.   window.status = " ";
  1179.   return true;
  1180. }
  1181.  
  1182. function _jmolSetCodebase(codebase) {
  1183.   _jmol.codebase = codebase ? codebase : ".";
  1184.   if (_jmol.debugAlert)
  1185.     alert("jmolCodebase=" + _jmol.codebase);
  1186. }
  1187.  
  1188. function _jmolOnloadResetForms() {
  1189.   // must be evaluated ONLY once
  1190.   _jmol.previousOnloadHandler = window.onload;
  1191.   window.onload =
  1192.   function() {
  1193.     with (_jmol) {
  1194.       if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
  1195.         var forms = document.forms;
  1196.         for (var i = forms.length; --i >= 0; )
  1197.           forms[i].reset();
  1198.       }
  1199.       if (previousOnloadHandler)
  1200.         previousOnloadHandler();
  1201.     }
  1202.   }
  1203. }
  1204.  
  1205. ////////////////////////////////////
  1206. /////extensions for getProperty/////
  1207. ////////////////////////////////////
  1208.  
  1209.  
  1210. function _jmolEvalJSON(s,key){
  1211.  s=s+""
  1212.  if(!s)return []
  1213.  if(s.charAt(0)!="{"){
  1214.         if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")
  1215.         return s
  1216.  }
  1217.  var A = eval("("+s+")")
  1218.  if(!A)return
  1219.  if(key && A[key])A=A[key]
  1220.  return A
  1221. }
  1222.  
  1223. function _jmolEnumerateObject(A,key){
  1224.  var sout=""
  1225.  if(typeof(A) == "string" && A!="null"){
  1226.         sout+="\n"+key+"=\""+A+"\""
  1227.  }else if(!isNaN(A)||A==null){
  1228.         sout+="\n"+key+"="+(A+""==""?"null":A)
  1229.  }else if(A.length){
  1230.     sout+=key+"=[]"
  1231.     for(var i=0;i<A.length;i++){
  1232.         sout+="\n"
  1233.         if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
  1234.                 sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")
  1235.         }else{
  1236.                 sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
  1237.         }
  1238.     }
  1239.  }else{
  1240.     if(key != ""){
  1241.         sout+=key+"={}"
  1242.         key+="."
  1243.     }
  1244.    
  1245.     for(var i in A){
  1246.         sout+="\n"
  1247.         if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
  1248.                 sout+=_jmolEnumerateObject(A[i],key+i)
  1249.         }else{
  1250.                 sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
  1251.         }
  1252.     }
  1253.  }
  1254.  return sout
  1255. }
  1256.  
  1257.  
  1258. function _jmolSortKey0(a,b){
  1259.  return (a[0]<b[0]?1:a[0]>b[0]?-1:0)
  1260. }
  1261.  
  1262. function _jmolSortMessages(A){
  1263.  if(!A || typeof(A)!="object")return []
  1264.  var B = []
  1265.  for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]
  1266.  if(B.length == 0) return
  1267.  B=B.sort(_jmolSortKey0)
  1268.  return B
  1269. }
  1270.  
  1271. /////////additional extensions //////////
  1272.  
  1273.  
  1274. function _jmolDomScriptLoad(URL){
  1275.  //open(URL) //to debug
  1276.  _jmol.servercall=URL
  1277.  var node = document.getElementById("_jmolScriptNode")
  1278.  if (node && _jmol.browser!="msie"){
  1279.     document.getElementsByTagName("HEAD")[0].removeChild(node)
  1280.     node=null
  1281.  }
  1282.  if (node) {
  1283.    node.setAttribute("src",URL)
  1284.  } else {
  1285.    node=document.createElement("script")
  1286.    node.setAttribute("id","_jmolScriptNode")
  1287.    node.setAttribute("type","text/javascript")
  1288.    node.setAttribute("src",URL)
  1289.    document.getElementsByTagName("HEAD")[0].appendChild(node)
  1290.  }
  1291. }
  1292.  
  1293.  
  1294. function _jmolExtractPostData(url){
  1295.  S=url.split("&POST:")
  1296.  var s=""
  1297.  for(var i=1;i<S.length;i++){
  1298.         KV=S[i].split("=")
  1299.         s+="&POSTKEY"+i+"="+KV[0]
  1300.         s+="&POSTVALUE"+i+"="+KV[1]
  1301.  }
  1302.  return "&url="+escape(S[0])+s
  1303. }
  1304.  
  1305. function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){
  1306.  //called by server, but in client
  1307.  //overload this function to customize return
  1308.  _jmol.remoteURL=remoteURL
  1309.  isError && alert(errorMessage)
  1310.  jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)
  1311. }
  1312.  
  1313. //////////user property/status functions/////////
  1314.  
  1315. function jmolGetStatus(strStatus,targetSuffix){
  1316.  return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))
  1317. }
  1318.  
  1319. function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {
  1320.  return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)
  1321. }
  1322.  
  1323. function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {
  1324.  var applet = _jmolGetApplet(targetSuffix);
  1325.  sValue == undefined && (sValue="");
  1326.  return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")
  1327. }
  1328.  
  1329. function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {
  1330.  sValue == undefined && (sValue = "")
  1331.  var applet = _jmolGetApplet(targetSuffix);
  1332.  try {
  1333.   return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")
  1334.  } catch(e) {
  1335.   return ""
  1336.  }
  1337. }
  1338.  
  1339. function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {
  1340.  sValue == undefined && (sValue = "")
  1341.  var applet = _jmolGetApplet(targetSuffix);
  1342.  return (applet ? applet.getProperty(sKey,sValue) : null)
  1343. }
  1344.  
  1345.  
  1346. function jmolDecodeJSON(s) {
  1347.  return _jmolEnumerateObject(_jmolEvalJSON(s),"")
  1348. }
  1349.  
  1350.  
  1351. ///////// synchronous scripting ////////
  1352.  
  1353. function jmolScriptWait(script, targetSuffix) {
  1354.   targetSuffix == undefined && (targetSuffix="0")
  1355.   var Ret=jmolScriptWaitAsArray(script, targetSuffix)
  1356.   var s = ""
  1357.   for(var i=Ret.length;--i>=0;)
  1358.   for(var j=0;j< Ret[i].length;j++)
  1359.         s+=Ret[i][j]+"\n"
  1360.   return s
  1361. }
  1362.  
  1363. function jmolScriptWaitOutput(script, targetSuffix) {
  1364.   targetSuffix == undefined && (targetSuffix="0")
  1365.   var ret = ""
  1366.   try{
  1367.    if (script) {
  1368.     _jmolCheckBrowser();
  1369.     var applet=_jmolGetApplet(targetSuffix);
  1370.     if (applet) ret += applet.scriptWaitOutput(script);
  1371.    }
  1372.   }catch(e){
  1373.   }
  1374.  return ret;
  1375. }
  1376.  
  1377. function jmolEvaluate(molecularMath, targetSuffix) {
  1378.  
  1379.   //carries out molecular math on a model
  1380.  
  1381.   targetSuffix == undefined && (targetSuffix="0")
  1382.   var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);
  1383.   var s = result.replace(/\-*\d+/,"")
  1384.   if (s == "" && !isNaN(parseInt(result)))return parseInt(result);
  1385.   var s = result.replace(/\-*\d*\.\d*/,"")
  1386.   if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);
  1387.   return result;
  1388. }
  1389.  
  1390. function jmolScriptEcho(script, targetSuffix) {
  1391.   // returns a newline-separated list of all echos from a script
  1392.   targetSuffix == undefined && (targetSuffix="0")
  1393.   var Ret=jmolScriptWaitAsArray(script, targetSuffix)
  1394.   var s = ""
  1395.   for(var i=Ret.length;--i>=0;)
  1396.   for(var j=Ret[i].length;--j>=0;)
  1397.         if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"
  1398.   return s.replace(/ \| /g, "\n")
  1399. }
  1400.  
  1401.  
  1402. function jmolScriptMessage(script, targetSuffix) {
  1403.   // returns a newline-separated list of all messages from a script, ending with "script completed\n"
  1404.   targetSuffix == undefined && (targetSuffix="0")
  1405.   var Ret=jmolScriptWaitAsArray(script, targetSuffix)
  1406.   var s = ""
  1407.   for(var i=Ret.length;--i>=0;)
  1408.   for(var j=Ret[i].length;--j>=0;)
  1409.         if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"
  1410.   return s.replace(/ \| /g, "\n")
  1411. }
  1412.  
  1413.  
  1414. function jmolScriptWaitAsArray(script, targetSuffix) {
  1415.  var ret = ""
  1416.  try{
  1417.   jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)
  1418.   if (script) {
  1419.     _jmolCheckBrowser();
  1420.     var applet=_jmolGetApplet(targetSuffix);
  1421.     if (applet) ret += applet.scriptWait(script);
  1422.     ret = _jmolEvalJSON(ret,"jmolStatus")
  1423.     if(typeof ret == "object")
  1424.         return ret
  1425.   }
  1426.  }catch(e){
  1427.  }
  1428.   return [[ret]]
  1429. }
  1430.  
  1431.  
  1432.  
  1433. ////////////   save/restore orientation   /////////////
  1434.  
  1435. function jmolSaveOrientation(id, targetSuffix) {  
  1436.  targetSuffix == undefined && (targetSuffix="0")
  1437.  return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo
  1438. }
  1439.  
  1440. function jmolRestoreOrientation(id, targetSuffix) {
  1441.  targetSuffix == undefined && (targetSuffix="0")
  1442.  var s=_jmol["savedOrientation"+id]
  1443.  if (!s || s == "")return
  1444.  s=s.replace(/1\.0/,"0")
  1445.  return jmolScriptWait(s,targetSuffix)
  1446. }
  1447.  
  1448. function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {
  1449.  arguments.length < 2 && (delay=1)
  1450.  targetSuffix == undefined && (targetSuffix="0")
  1451.  var s=_jmol["savedOrientation"+id]
  1452.  if (!s || s == "")return
  1453.  s=s.replace(/1\.0/,delay)
  1454.  return jmolScriptWait(s,targetSuffix)
  1455. }
  1456.  
  1457. ////////////  add parameter /////////////
  1458. /*
  1459.  * for adding callbacks or other parameters. Use:
  1460.  
  1461.    jmolSetDocument(0)
  1462.    var s= jmolApplet(....)
  1463.    s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")
  1464.    document.write(s)
  1465.    jmolSetDocument(document) // if you want to then write buttons and such normally
  1466.  
  1467.  */
  1468.  
  1469. function jmolAppletAddParam(appletCode,name,value){
  1470.   return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))
  1471. }
  1472.  
  1473. ///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////
  1474.  
  1475. function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){
  1476.  
  1477.  _jmol.thismodel || (_jmol.thismodel = "1crn")
  1478.  _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
  1479.  _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")
  1480.  _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")
  1481.  fileformat || (fileformat="PDB")
  1482.  pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))
  1483.  if(!pdbid || pdbid.length != 4)return ""
  1484.  targetSuffix || (targetSuffix="0")
  1485.  optionalscript || (optionalscript="")
  1486.  var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())
  1487.  fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))
  1488.  _jmol.optionalscript=optionalscript
  1489.  _jmol.thismodel=pdbid
  1490.  _jmol.thistargetsuffix=targetSuffix
  1491.  _jmol.thisurl=url
  1492.  _jmol.modelArray = []
  1493.  url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
  1494.  _jmolDomScriptLoad(url)
  1495.  return url
  1496. }
  1497.  
  1498. /////////////// St. Olaf College AJAX server -- ANY URL ///////////
  1499.  
  1500. function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){
  1501.  _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
  1502.  _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")
  1503.  url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))
  1504.  userid || (userid="0")
  1505.  targetSuffix || (targetSuffix="0")
  1506.  optionalscript || (optionalscript="")
  1507.  _jmol.optionalscript=optionalscript
  1508.  _jmol.thistargetsuffix=targetSuffix
  1509.  _jmol.modelArray = []
  1510.  _jmol.thisurl = url
  1511.  url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
  1512.  _jmolDomScriptLoad(url)
  1513. }
  1514.  
  1515.  
  1516. /////////////// Mineralogical Society of America (MSA) data /////////
  1517.  
  1518. function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){
  1519.  
  1520.  _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")
  1521.  _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")
  1522.  _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")
  1523.  key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))
  1524.  if(!key)return ""
  1525.  value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))
  1526.  if(!value)return ""
  1527.  targetSuffix || (targetSuffix="0")
  1528.  optionalscript || (optionalscript="")
  1529.  optionalscript == 1 && (optionalscript='load "" {1 1 1}')
  1530.  var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)
  1531.  _jmol.optionalscript=optionalscript
  1532.  _jmol.thiskeyMSA=key
  1533.  _jmol.thismodelMSA=value
  1534.  _jmol.thistargetsuffix=targetSuffix
  1535.  _jmol.thisurl=url
  1536.  _jmol.modelArray = []
  1537.  loadModel=_jmolLoadModel
  1538.  _jmolDomScriptLoad(url)
  1539.  return url
  1540. }
  1541.  
  1542.  
  1543.  
  1544. function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){
  1545.  userid || (userid="0")
  1546.  targetSuffix || (targetSuffix="0")
  1547.  optionalscript || (optionalscript="")
  1548.  _jmol.optionalscript=optionalscript
  1549.  _jmol.thismodel=userid
  1550.  _jmol.thistargetsuffix=targetSuffix
  1551.  _jmol.modelArray = []
  1552.  _jmol.thisurl = url
  1553.  url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix
  1554.  _jmolDomScriptLoad(url)
  1555. }
  1556.  
  1557.  
  1558. //// in case Jmol library has already been loaded:
  1559.  
  1560. }catch(e){}
  1561.  
  1562. ///////////////moving atoms //////////////
  1563.  
  1564. // HIGHLY experimental!!
  1565.  
  1566. function jmolSetAtomCoord(i,x,y,z,targetSuffix){
  1567.     _jmolCheckBrowser();
  1568.       var applet=_jmolGetApplet(targetSuffix);
  1569.       if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)
  1570. }
  1571.  
  1572. function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){
  1573.     _jmolCheckBrowser();
  1574.       var applet=_jmolGetApplet(targetSuffix);
  1575.       if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)
  1576. }
  1577.  
  1578.  
  1579. ///////////////applet fake for testing buttons/////////////
  1580.  
  1581.  
  1582. if(_jmol.useNoApplet){
  1583.         jmolApplet = function(w){
  1584.                 var s="<table style='background-color:black' width="+w+"><tr height="+w+">"
  1585.                 +"<td align=center valign=center style='background-color:white'>"
  1586.                 +"Applet would be here"
  1587.                 +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"
  1588.                 +"</td></tr></table>"
  1589.                 return _jmolDocumentWrite(s)
  1590.         }
  1591.  
  1592.         _jmolFindApplet = function(){return jmolApplet0}
  1593.  
  1594.         jmolApplet0 = {
  1595.          script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}
  1596.         ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script}
  1597.         ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}
  1598.         }
  1599. }
  1600.  
  1601.  
  1602. ///////////////////////////////////////////
  1603.  
  1604.   //  This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility
  1605.   /*
  1606.         Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).
  1607.         targetSuffix is optional and defaults to zero (first applet in page).
  1608.         Both w and h are optional, but needed if you want to use targetSuffix.
  1609.                 h defaults to w
  1610.                 w defaults to 100% of window
  1611.         If either w or h is between 0 and 1, then it is taken as percent/100.
  1612.         If either w or h is greater than 1, then it is taken as a size (pixels).
  1613.         */
  1614. function jmolResize(w,h,targetSuffix) {
  1615.  _jmol.alerted = true;
  1616.  var percentW = (!w ? 100 : w <= 1  && w > 0 ? w * 100 : 0);
  1617.  var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);
  1618.  if (_jmol.browser=="msie") {
  1619.    var width=document.body.clientWidth;
  1620.    var height=document.body.clientHeight;
  1621.  } else {
  1622.    var netscapeScrollWidth=15;
  1623.    var width=window.innerWidth - netscapeScrollWidth;
  1624.    var height=window.innerHeight-netscapeScrollWidth;
  1625.  }
  1626.  var applet = _jmolGetApplet(targetSuffix);
  1627.  if(!applet)return;
  1628.  applet.style.width = (percentW ? width * percentW/100 : w)+"px";
  1629.  applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";
  1630.  //title=width +  " " + height + " " + (new Date());
  1631. }
  1632.  
  1633. // 13 Jun 09 -- makes jmolResize() obsolete  (kept for backwards compatibility)
  1634. function jmolResizeApplet(size,targetSuffix) {
  1635.  // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]
  1636.  //  Special case: an empty value for width or height is accepted, meaning no change in that dimension.
  1637.  _jmol.alerted = true;
  1638.  var applet = _jmolGetApplet(targetSuffix);
  1639.  if(!applet)return;
  1640.  var sz = _jmolGetAppletSize(size, "px");
  1641.  sz[0] && (applet.style.width = sz[0]);
  1642.  sz[1] && (applet.style.height = sz[1]);
  1643. }
  1644.  
  1645. function _jmolGetAppletSize(size, units) {
  1646.         /* Accepts single number or 2-value array, each one can be one of:
  1647.            percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)
  1648.            [width, height] array of strings is returned, with units added if specified.
  1649.            Percent is relative to container div or element (which should have explicitly set size).
  1650.         */
  1651.   var width, height;
  1652.   if ( (typeof size) == "object" && size != null ) {
  1653.     width = size[0]; height = size[1];
  1654.   } else {
  1655.     width = height = size;
  1656.   }
  1657.   return [_jmolFixDim(width, units), _jmolFixDim(height, units)];
  1658. }
  1659.  
  1660. function _jmolFixDim(x, units) {
  1661.   var sx = "" + x;
  1662.   return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])
  1663.         : sx.indexOf("%") == sx.length-1 ? sx
  1664.         : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"
  1665.         : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]
  1666.                 : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]
  1667.             : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1]
  1668.         : x) + (units ? units : ""));
  1669. }
  1670.  
  1671.  
  1672.  
  1673.  
  1674.