Subversion Repositories wimsdev

Rev

Rev 1365 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* $RCSfile: Jmol.js,v $
  2.  * $Author: migueljmol $
  3.  * $Date: 2004/12/11 22:22:10 $
  4.  * $Revision: 1.28 $
  5.  *
  6.  * Copyright (C) 2004  The Jmol Development Team
  7.  *
  8.  * Contact: jmol-developers@lists.sf.net
  9.  *
  10.  *  This library is free software; you can redistribute it and/or
  11.  *  modify it under the terms of the GNU Lesser General Public
  12.  *  License as published by the Free Software Foundation; either
  13.  *  version 2.1 of the License, or (at your option) any later version.
  14.  *
  15.  *  This library is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18.  *  Lesser General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU Lesser General Public
  21.  *  License along with this library; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  23.  *  02111-1307  USA.
  24.  */
  25.  
  26. // for documentation see www.jmol.org/jslibrary
  27.  
  28. var undefined; // for IE 5 ... wherein undefined is undefined
  29.  
  30. ////////////////////////////////////////////////////////////////
  31. // Basic Scripting infrastruture
  32. ////////////////////////////////////////////////////////////////
  33.  
  34. function jmolInitialize(codebaseDirectory) {
  35.   if (_jmol.initialized) {
  36.     alert("jmolInitialize() should only be called *ONCE* within a page");
  37.     return;
  38.   }
  39.   if (! codebaseDirectory) {
  40.     alert("codebaseDirectory is a required parameter to jmolInitialize");
  41.     codebaseDirectory = ".";
  42.   }
  43.   if (codebaseDirectory.indexOf("http://") == 0 ||
  44.       codebaseDirectory.indexOf("https://") == 0)
  45.     alert("codebaseDirectory should be directory relative,\n" +
  46.           "not be an absolute URL : " + codebaseDirectory);
  47.   else if (codebaseDirectory.charAt(0) == '/')
  48.     alert("codebaseDirectory should be directory relative,\n" +
  49.           "not relative to the root of the web server : " + codebaseDirectory);
  50.   _jmolSetCodebase(codebaseDirectory);
  51.   _jmolOnloadResetForms();
  52.   _jmol.initialized = true;
  53. }
  54.  
  55. function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
  56.   _jmolInitCheck();
  57.   _jmol.boxbgcolor = boxbgcolor;
  58.   if (boxfgcolor)
  59.     _jmol.boxfgcolor = boxfgcolor
  60.   else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
  61.     _jmol.boxfgcolor = "black";
  62.   else
  63.     _jmol.boxfgcolor = "white";
  64.   if (progresscolor)
  65.     _jmol.progresscolor = progresscolor;
  66.   if (_jmol.debugAlert)
  67.     alert(" boxbgcolor=" + _jmol.boxbgcolor +
  68.           " boxfgcolor=" + _jmol.boxfgcolor +
  69.           " progresscolor=" + _jmol.progresscolor);
  70. }
  71.  
  72. function jmolApplet(size, script, nameSuffix) {
  73.   _jmolInitCheck();
  74.   _jmolApplet(size, null, script, nameSuffix);
  75. }
  76.  
  77. ////////////////////////////////////////////////////////////////
  78. // Basic controls
  79. ////////////////////////////////////////////////////////////////
  80.  
  81. function jmolButton(script, label, id) {
  82.   _jmolInitCheck();
  83.   var scriptIndex = _jmolAddScript(script);
  84.   if (label == undefined || label == null)
  85.     label = script.substring(0, 32);
  86.   if (id == undefined || id == null)
  87.     id = "jmolButton" + _jmol.buttonCount;
  88.   ++_jmol.buttonCount;
  89.   var t = "<input type='button' name='" + id + "' id='" + id +
  90.           "' value='" + label +
  91.           "' onClick='_jmolClick(" + scriptIndex + _jmol.targetText +
  92.           ")' onMouseover='_jmolMouseOver(" + scriptIndex +
  93.           ");return true' onMouseout='_jmolMouseOut()' " +
  94.           _jmol.buttonCssText + "/>";
  95.   if (_jmol.debugAlert)
  96.     alert(t);
  97.   document.write(t);
  98. }
  99.  
  100. function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
  101.                       labelHtml, isChecked, id) {
  102.   _jmolInitCheck();
  103.   if (id == undefined || id == null)
  104.     id = "jmolCheckbox" + _jmol.checkboxCount;
  105.   ++_jmol.checkboxCount;
  106.   if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
  107.       scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
  108.     alert("jmolCheckbox requires two scripts");
  109.     return;
  110.   }
  111.   if (labelHtml == undefined || labelHtml == null) {
  112.     alert("jmolCheckbox requires a label");
  113.     return;
  114.   }
  115.   var indexChecked = _jmolAddScript(scriptWhenChecked);
  116.   var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
  117.   var t = "<input type='checkbox' name='" + id + "' id='" + id +
  118.           "' onClick='_jmolCbClick(this," +
  119.           indexChecked + "," + indexUnchecked + _jmol.targetText +
  120.           ")' onMouseover='_jmolCbOver(this," + indexChecked + "," +
  121.           indexUnchecked +
  122.           ");return true' onMouseout='_jmolMouseOut()' " +
  123.           (isChecked ? "checked " : "") + _jmol.checkboxCssText + "/>" +
  124.           labelHtml;
  125.   if (_jmol.debugAlert)
  126.     alert(t);
  127.   document.write(t);
  128. }
  129.  
  130. function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName) {
  131.   _jmolInitCheck();
  132.   var type = typeof arrayOfRadioButtons;
  133.   if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
  134.     alert("invalid arrayOfRadioButtons");
  135.     return;
  136.   }
  137.   if (separatorHtml == undefined || separatorHtml == null)
  138.     separatorHtml = "&nbsp; ";
  139.   var length = arrayOfRadioButtons.length;
  140.   var t = "";
  141.   jmolStartNewRadioGroup();
  142.   for (var i = 0; i < length; ++i) {
  143.     var radio = arrayOfRadioButtons[i];
  144.     type = typeof radio;
  145.     if (type == "object") {
  146.       t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName);
  147.     } else {
  148.       t += _jmolRadio(radio, null, null, separatorHtml, groupName);
  149.     }
  150.   }
  151.   if (_jmol.debugAlert)
  152.     alert(t);
  153.   document.write(t);
  154. }
  155.  
  156. function jmolLink(script, text, id) {
  157.   _jmolInitCheck();
  158.   if (id == undefined || id == null)
  159.     id = "jmolLink" + _jmol.linkCount;
  160.   ++_jmol.linkCount;
  161.   var scriptIndex = _jmolAddScript(script);
  162.   var t = "<a name='" + id + "' id='" + id +
  163.           "' href='javascript:_jmolClick(" + scriptIndex +
  164.           _jmol.targetText +
  165.           ");' onMouseover='_jmolMouseOver(" + scriptIndex +
  166.           ");return true;' onMouseout='_jmolMouseOut()' " +
  167.           _jmol.linkCssText + ">" + text + "</a>";
  168.   if (_jmol.debugAlert)
  169.     alert(t);
  170.   document.write(t);
  171. }
  172.  
  173. function jmolMenu(arrayOfMenuItems, size, id) {
  174.   _jmolInitCheck();
  175.   if (id == undefined || id == null)
  176.     id = "jmolMenu" + _jmol.menuCount;
  177.   ++_jmol.menuCount;
  178.   var type = typeof arrayOfMenuItems;
  179.   if (type != null && type == "object" && arrayOfMenuItems.length) {
  180.     var length = arrayOfMenuItems.length;
  181.     if (typeof size != "number" || size == 1)
  182.       size = null;
  183.     else if (size < 0)
  184.       size = length;
  185.     var sizeText = size ? " size='" + size + "' " : "";
  186.     var t = "<select name='" + id + "' id='" + id +
  187.             "' onChange='_jmolMenuSelected(this" +
  188.             _jmol.targetText + ")'" +
  189.             sizeText + _jmol.menuCssText + ">";
  190.     for (var i = 0; i < length; ++i) {
  191.       var menuItem = arrayOfMenuItems[i];
  192.       type = typeof menuItem;
  193.       var script, text;
  194.       var isSelected = undefined;
  195.       if (type == "object" && menuItem != null) {
  196.         script = menuItem[0];
  197.         text = menuItem[1];
  198.         isSelected = menuItem[2];
  199.       } else {
  200.         script = text = menuItem;
  201.       }
  202.       if (text == undefined || text == null)
  203.         text = script;
  204.       var scriptIndex = _jmolAddScript(script);
  205.       var selectedText = isSelected ? "' selected>" : "'>";
  206.       t += "<option value='" + scriptIndex + selectedText + text + "</option>";
  207.     }
  208.     t += "</select>";
  209.     if (_jmol.debugAlert)
  210.       alert(t);
  211.     document.write(t);
  212.   }
  213. }
  214.  
  215. function jmolHtml(html) {
  216.   document.write(html);
  217. }
  218.  
  219. function jmolBr() {
  220.   document.write("<br />");
  221. }
  222.  
  223. ////////////////////////////////////////////////////////////////
  224. // advanced scripting functions
  225. ////////////////////////////////////////////////////////////////
  226.  
  227. function jmolDebugAlert(enableAlerts) {
  228.   _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
  229. }
  230.  
  231. function jmolAppletInline(size, inlineModel, script, nameSuffix) {
  232.   _jmolApplet(size, _jmolConvertInline(inlineModel), script, nameSuffix);
  233. }
  234.  
  235. function jmolSetTarget(targetSuffix) {
  236.   _jmol.targetSuffix = targetSuffix;
  237.   _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : "";
  238. }
  239.  
  240. function jmolScript(script, targetSuffix) {
  241.   if (script) {
  242.     _jmolCheckBrowser();
  243.     var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
  244.     var applet = _jmolFindApplet(target);
  245.     if (applet)
  246.       return applet.script(script);
  247.     else
  248.       alert("could not find applet " + target);
  249.   }
  250. }
  251.  
  252. function jmolLoadInline(model, targetSuffix) {
  253.   if (model) {
  254.     var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
  255. //    while (! _jmol.ready[target])
  256. //      alert("The Jmol applet " + target + " is not loaded yet");
  257. //    if (! _jmol.ready[target])
  258. //      alert("The Jmol applet " + target + " is not loaded yet");
  259. //    if (document.applets[target] && ! document.applets[target].isActive())
  260. //       alert("The Jmol applet " + target + " is not yet active");
  261. //    else {
  262.       var applet = _jmolFindApplet(target);
  263.       if (applet)
  264.         return applet.loadInline(model);
  265.       else
  266.         alert("could not find applet " + target);
  267. //    }
  268.   }
  269. }
  270.  
  271. function jmolStartNewRadioGroup() {
  272.   ++_jmol.radioGroupCount;
  273. }
  274.  
  275. function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName) {
  276.   _jmolInitCheck();
  277.   if (_jmol.radioGroupCount == 0)
  278.     ++_jmol.radioGroupCount;
  279.   var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName);
  280.   if (_jmol.debugAlert)
  281.     alert(t);
  282.   document.write(t);
  283. }
  284.  
  285. function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
  286.   if (typeof action == "string") {
  287.     action = action.toLowerCase();
  288.     if (action != "alert" && action != "redirect" && action != "popup")
  289.       action = null;
  290.   }
  291.   if (typeof action != "string")
  292.     alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
  293.           "action must be 'alert', 'redirect', or 'popup'");
  294.   else {
  295.     if (typeof urlOrMessage != "string")
  296.       alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
  297.             "urlOrMessage must be a string");
  298.     else {
  299.       _jmol.checkBrowserAction = action;
  300.       _jmol.checkBrowserUrlOrMessage = urlOrMessage;
  301.     }
  302.   }
  303.   if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
  304.     _jmolCheckBrowser();
  305. }
  306.  
  307. ////////////////////////////////////////////////////////////////
  308. // Cascading Style Sheet Class support
  309. ////////////////////////////////////////////////////////////////
  310.  
  311. function jmolSetAppletCssClass(appletCssClass) {
  312.   if (_jmol.hasGetElementById) {
  313.     _jmol.appletCssClass = appletCssClass;
  314.     _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
  315.   }
  316. }
  317.  
  318. function jmolSetButtonCssClass(buttonCssClass) {
  319.   if (_jmol.hasGetElementById) {
  320.     _jmol.buttonCssClass = buttonCssClass;
  321.     _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
  322.   }
  323. }
  324.  
  325. function jmolSetCheckboxCssClass(checkboxCssClass) {
  326.   if (_jmol.hasGetElementById) {
  327.     _jmol.checkboxCssClass = checkboxCssClass;
  328.     _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
  329.   }
  330. }
  331.  
  332. function jmolSetRadioCssClass(radioCssClass) {
  333.   if (_jmol.hasGetElementById) {
  334.     _jmol.radioCssClass = radioCssClass;
  335.     _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
  336.   }
  337. }
  338.  
  339. function jmolSetLinkCssClass(linkCssClass) {
  340.   if (_jmol.hasGetElementById) {
  341.     _jmol.linkCssClass = linkCssClass;
  342.     _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
  343.   }
  344. }
  345.  
  346. function jmolSetMenuCssClass(menuCssClass) {
  347.   if (_jmol.hasGetElementById) {
  348.     _jmol.menuCssClass = menuCssClass;
  349.     _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
  350.   }
  351. }
  352.  
  353. ////////////////////////////////////////////////////////////////
  354. // functions for INTERNAL USE ONLY which are subject to change
  355. // use at your own risk ... you have been WARNED!
  356. ////////////////////////////////////////////////////////////////
  357.  
  358. var _jmol = {
  359.  
  360. debugAlert: false,
  361. bgcolor: "black",
  362. progresscolor: "blue",
  363. boxbgcolor: "black",
  364. boxfgcolor: "white",
  365. boxmessage: "Downloading JmolApplet ...",
  366.  
  367. codebase: ".",
  368. modelbase: ".",
  369.  
  370. appletCount: 0,
  371.  
  372. buttonCount: 0,
  373. checkboxCount: 0,
  374. linkCount: 0,
  375. menuCount: 0,
  376. radioCount: 0,
  377. radioGroupCount: 0,
  378.  
  379. appletCssClass: null,
  380. appletCssText: "",
  381. buttonCssClass: null,
  382. buttonCssText: "",
  383. checkboxCssClass: null,
  384. checkboxCssText: "",
  385. radioCssClass: null,
  386. radioCssText: "",
  387. linkCssClass: null,
  388. linkCssText: "",
  389. menuCssClass: null,
  390. menuCssText: "",
  391.  
  392. targetSuffix: 0,
  393. targetText: "",
  394. scripts: [""],
  395.  
  396. ua: navigator.userAgent.toLowerCase(),
  397. uaVersion: parseFloat(navigator.appVersion),
  398.  
  399. os: "unknown",
  400. browser: "unknown",
  401. browserVersion: 0,
  402. hasGetElementById: !!document.getElementById,
  403. isJavaEnabled: navigator.javaEnabled(),
  404. isNetscape47Win: false,
  405.  
  406. isBrowserCompliant: false,
  407. isJavaCompliant: false,
  408. isFullyCompliant: false,
  409.  
  410. initialized: false,
  411. initChecked: false,
  412.  
  413. browserChecked: false,
  414. checkBrowserAction: "alert",
  415. checkBrowserUrlOrMessage: null,
  416.  
  417. previousOnloadHandler: null,
  418. ready: {}
  419. }
  420.  
  421. with (_jmol) {
  422.   function _jmolTestUA(candidate) {
  423.     var ua = _jmol.ua;
  424.     var index = ua.indexOf(candidate);
  425.     if (index < 0)
  426.       return false;
  427.     _jmol.browser = candidate;
  428.     _jmol.browserVersion = parseFloat(ua.substring(index + candidate.length+1));
  429.     return true;
  430.   }
  431.  
  432.   function _jmolTestOS(candidate) {
  433.     if (_jmol.ua.indexOf(candidate) < 0)
  434.       return false;
  435.     _jmol.os = candidate;
  436.     return true;
  437.   }
  438.  
  439.   _jmolTestUA("konqueror") ||
  440.   _jmolTestUA("safari") ||
  441.   _jmolTestUA("omniweb") ||
  442.   _jmolTestUA("opera") ||
  443.   _jmolTestUA("webtv") ||
  444.   _jmolTestUA("icab") ||
  445.   _jmolTestUA("msie") ||
  446.   (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla"));
  447.  
  448.   _jmolTestOS("linux") ||
  449.   _jmolTestOS("unix") ||
  450.   _jmolTestOS("mac") ||
  451.   _jmolTestOS("win");
  452.  
  453.   isNetscape47Win = (os == "win" && browser == "mozilla" &&
  454.                      browserVersion >= 4.78 && browserVersion <= 4.8);
  455.  
  456.   if (os == "win") {
  457.     isBrowserCompliant = hasGetElementById || isNetscape47Win;
  458.   } else if (os == "mac") { // mac is the problem child :-(
  459.     if (browser == "mozilla" && browserVersion >= 5) {
  460.       // miguel 2004 11 17
  461.       // checking the plugins array does not work because
  462.       // Netscape 7.2 OS X still has Java 1.3.1 listed even though
  463.       // javaplugin.sf.net is installed to upgrade to 1.4.2
  464.       eval("try {var v = java.lang.System.getProperty('java.version');" +
  465.            " _jmol.isBrowserCompliant = v >= '1.4.2';" +
  466.            " } catch (e) { }");
  467.     } else if (browser == "opera" && browserVersion <= 7.54) {
  468.       isBrowserCompliant = false;
  469.     } else {
  470.       isBrowserCompliant = hasGetElementById &&
  471.         !((browser == "msie") ||
  472.           (browser == "safari" && browserVersion < 125.1));
  473.     }
  474.   } else if (os == "linux" || os == "unix") {
  475.     if (browser == "konqueror" && browserVersion <= 3.3)
  476.       isBrowserCompliant = false;
  477.     else
  478.       isBrowserCompliant = hasGetElementById;
  479.   } else { // other OS
  480.     isBrowserCompliant = hasGetElementById;
  481.   }
  482.  
  483.   // possibly more checks in the future for this
  484.   isJavaCompliant = isJavaEnabled;
  485.  
  486.   isFullyCompliant = isBrowserCompliant && isJavaCompliant;
  487. }
  488.  
  489. function _jmolApplet(size, inlineModel, script, nameSuffix) {
  490.   with (_jmol) {
  491.     if (! nameSuffix)
  492.       nameSuffix = appletCount;
  493.     ++appletCount;
  494.     if (! script)
  495.       script = "select *";
  496.     var sz = _jmolGetAppletSize(size);
  497.     var t;
  498.     t = "<applet name='jmolApplet" + nameSuffix + "' id='jmolApplet" + nameSuffix +
  499.         "' " + appletCssText +
  500.         " code='JmolApplet' archive='JmolApplet.jar'\n" +
  501.         " codebase='" + codebase + "'\n" +
  502.         " width='" + sz[0] + "' height='" + sz[1] +
  503.         "' mayscript='true'>\n" +
  504.         "  <param name='progressbar' value='true' />\n" +
  505.         "  <param name='progresscolor' value='" +
  506.         progresscolor + "' />\n" +
  507.         "  <param name='boxmessage' value='" +
  508.         boxmessage + "' />\n" +
  509.         "  <param name='boxbgcolor' value='" +
  510.         boxbgcolor + "' />\n" +
  511.         "  <param name='boxfgcolor' value='" +
  512.         boxfgcolor + "' />\n" +
  513.         "  <param name='ReadyCallback' value='_jmolReadyCallback' />\n";
  514.  
  515.     if (inlineModel)
  516.       t += "  <param name='loadInline' value='" + inlineModel + "' />\n";
  517.     if (script)
  518.       t += "  <param name='script' value='" + script + "' />\n";
  519.     t += "</applet>";
  520.     jmolSetTarget(nameSuffix);
  521.     ready["jmolApplet" + nameSuffix] = false;
  522.     if (_jmol.debugAlert)
  523.       alert(t);
  524.     document.write(t);
  525.   }
  526. }
  527.  
  528. function _jmolInitCheck() {
  529.   if (_jmol.initChecked)
  530.     return;
  531.   _jmol.initChecked = true;
  532.   if (_jmol.initialized)
  533.     return;
  534.   alert("jmolInitialize({codebase}, {badBrowseURL}, {badJavaURL})\n" +
  535.         "  must be called before any other Jmol.js functions");
  536. }
  537.  
  538. function _jmolCheckBrowser() {
  539.   with (_jmol) {
  540.     if (browserChecked)
  541.       return;
  542.     browserChecked = true;
  543.  
  544.     if (isFullyCompliant)
  545.       return true;
  546.  
  547.     if (checkBrowserAction == "redirect")
  548.       location.href = checkBrowserUrlOrMessage;
  549.     else if (checkBrowserAction == "popup")
  550.       _jmolPopup(checkBrowserUrlOrMessage);
  551.     else {
  552.       var msg = checkBrowserUrlOrMessage;
  553.       if (msg == null)
  554.         msg = "Your web browser is not fully compatible with Jmol\n\n" +
  555.               "brower: " + browser +
  556.               "   version: " + browserVersion +
  557.               "   os: " + os +
  558.               "\n\n" + ua;
  559.       alert(msg);
  560.     }
  561.   }
  562.   return false;
  563. }
  564.  
  565. function _jmolPopup(url) {
  566.   var popup = window.open(url, "JmolPopup",
  567.                           "left=150,top=150,height=400,width=600," +
  568.                           "directories=yes,location=yes,menubar=yes," +
  569.                           "toolbar=yes," +
  570.                           "resizable=yes,scrollbars=yes,status=yes");
  571.   if (popup.focus)
  572.     poup.focus();
  573. }
  574.  
  575. function _jmolReadyCallback(name) {
  576.   if (_jmol.debugAlert)
  577.     alert(name + " is ready");
  578.   _jmol.ready["" + name] = true;
  579. }
  580.  
  581. function _jmolConvertInline(model) {
  582.   var inlineModel = model.replace(/\r|\n|\r\n/g, "|");
  583.   if (_jmol.debugAlert)
  584.     alert("inline model:\n" + inlineModel);
  585.   return inlineModel;
  586. }
  587.  
  588. function _jmolGetAppletSize(size) {
  589.   var width, height;
  590.   var type = typeof size;
  591.   if (type == "number")
  592.     width = height = size;
  593.   else if (type == "object" && size != null) {
  594.     width = size[0]; height = size[1];
  595.   }
  596.   if (! (width >= 25 && width <= 2000))
  597.     width = 300;
  598.   if (! (height >= 25 && height <= 2000))
  599.     height = 300;
  600.   return [width, height];
  601. }
  602.  
  603. function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName) {
  604.   ++_jmol.radioCount;
  605.   if (groupName == undefined || groupName == null)
  606.     groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1);
  607.   if (!script)
  608.     return "";
  609.   if (labelHtml == undefined || labelHtml == null)
  610.     labelHtml = script.substring(0, 32);
  611.   if (! separatorHtml)
  612.     separatorHtml = "";
  613.   var scriptIndex = _jmolAddScript(script);
  614.   return "<input name='" + groupName +
  615.          "' type='radio' onClick='_jmolClick(" +
  616.          scriptIndex + _jmol.targetText +
  617.          ");return true;' onMouseover='_jmolMouseOver(" +
  618.          scriptIndex +
  619.          ");return true;' onMouseout='_jmolMouseOut()' " +
  620.          (isChecked ? "checked " : "") + _jmol.radioCssText + "/>" +
  621.          labelHtml + separatorHtml;
  622. }
  623.  
  624. function _jmolFindApplet(target) {
  625.   // first look for the target in the current window
  626.   var applet = _jmolSearchFrames(window, target);
  627.   if (applet == undefined)
  628.     applet = _jmolSearchFrames(top, target); // look starting in top frame
  629.   return applet;
  630. }
  631.  
  632. function _jmolSearchFrames(win, target) {
  633.   var applet;
  634.   var frames = win.frames;
  635.   if (frames && frames.length) { // look in all the frames below this window
  636.     for (var i = 0; i < frames.length; ++i) {
  637.       applet = _jmolSearchFrames(frames[i++], target);
  638.       if (applet)
  639.         break;
  640.     }
  641.   } else { // look for the applet in this window
  642.     var doc = win.document;
  643. // getElementById fails on MacOSX Safari & Mozilla     
  644.     if (doc.applets)
  645.       applet = doc.applets[target];
  646.     else
  647.       applet = doc[target];
  648.   }
  649.   return applet;
  650. }
  651.  
  652. function _jmolAddScript(script) {
  653.   if (! script)
  654.     return 0;
  655.   var index = _jmol.scripts.length;
  656.   _jmol.scripts[index] = script;
  657.   return index;
  658. }
  659.  
  660. function _jmolClick(scriptIndex, targetSuffix) {
  661.   jmolScript(_jmol.scripts[scriptIndex], targetSuffix);
  662. }
  663.  
  664. function _jmolMenuSelected(menuObject, targetSuffix) {
  665.   var scriptIndex = menuObject.value;
  666.   if (scriptIndex != undefined) {
  667.     jmolScript(_jmol.scripts[scriptIndex], targetSuffix);
  668.     return;
  669.   }
  670.   var length = menuObject.length;
  671.   if (typeof length == "number") {
  672.     for (var i = 0; i < length; ++i) {
  673.       if (menuObject[i].selected) {
  674.         _jmolClick(menuObject[i].value, targetSuffix);
  675.         return;
  676.       }
  677.     }
  678.   }
  679.   alert("?Que? menu selected bug #8734");
  680. }
  681.  
  682. function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
  683.   _jmolClick(ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
  684. }
  685.  
  686. function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
  687.   window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
  688. }
  689.  
  690. function _jmolMouseOver(scriptIndex) {
  691.   window.status = _jmol.scripts[scriptIndex];
  692. }
  693.  
  694. function _jmolMouseOut() {
  695.   window.status = " ";
  696.   return true;
  697. }
  698.  
  699. function _jmolSetCodebase(codebase) {
  700.   _jmol.codebase = codebase ? codebase : ".";
  701.   if (_jmol.debugAlert)
  702.     alert("jmolCodebase=" + _jmol.codebase);
  703. }
  704.  
  705. function _jmolOnloadResetForms() {
  706.   _jmol.previousOnloadHandler = window.onload;
  707.   window.onload =
  708.   function() {
  709. //    alert("onloadResetForms");
  710.     with (_jmol) {
  711.       if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
  712.         var forms = document.forms;
  713.         if (!forms || forms.length == 0) {
  714.           alert("<form> tags seem to be missing\n" +
  715.                 "Jmol/HTML input controls must be contained " +
  716.                 "within form tags"
  717. //                + "\n\n" + forms + " forms.length=" + forms.length +
  718. //                " typeof=" + (typeof forms)
  719.                 );
  720.         } else {
  721.           for (var i = forms.length; --i >= 0; )
  722.             forms[i].reset();
  723.         }
  724.       }
  725.       if (previousOnloadHandler)
  726.         previousOnloadHandler();
  727.     }
  728.   }
  729. }
  730.  
  731.