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