Best JavaScript code snippet using playwright-internal
UI.js
Source:UI.js
...17molmil.UI.prototype.init=function() {18 if (! this.canvas.parentNode.classList.contains("molmil_UI_container")) {19 var container = molmil_dep.dcE("span"); container.classList.add("molmil_UI_container");20 this.canvas.parentNode.replaceChild(container, this.canvas);21 container.pushNode(this.canvas);22 }23 24 var cont, icon;25 cont = document.createElement("span");26 cont.className = "molmil_UI_LB unselectableText";27 this.LM = icon = document.createElement("span");28 icon.className = "molmil_UI_LB_icon";29 icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" style="enable-background:new 0 0 32 32;/* background-color: red; */" version="1.1" viewBox="0 0 32 32" xml:space="preserve"><path d="M4,10h24c1.104,0,2-0.896,2-2s-0.896-2-2-2H4C2.896,6,2,6.896,2,8S2.896,10,4,10z M28,14H4c-1.104,0-2,0.896-2,2 s0.896,2,2,2h24c1.104,0,2-0.896,2-2S29.104,14,28,14z M28,22H4c-1.104,0-2,0.896-2,2s0.896,2,2,2h24c1.104,0,2-0.896,2-2 S29.104,22,28,22z" fill="red"/></svg>';30 31 icon.UI = this;32 icon.onclick = function() {33 this.UI.showLM(this);34 };35 cont.appendChild(icon);36 (this.canvas ? this.canvas.parentNode : document.body).appendChild(cont);37 cont = document.createElement("span");38 cont.className = "molmil_UI_RB unselectableText";39 this.RM = icon = document.createElement("div");40 icon.className = "molmil_UI_RB_icon";41 icon.innerHTML = "<<br/><<br/><";42 icon.title = "Structures panel: contains a list of all loaded entries";43 icon.UI = this;44 icon.onclick = function() {45 this.UI.showRM(this);46 };47 cont.appendChild(icon);48 cont.menu = cont.pushNode("div"); cont.menu.style.display = "none";49 cont.menu.className = "molmil_UI_RM";50 (this.canvas ? this.canvas.parentNode : document.body).appendChild(cont);51};52molmil.UI.prototype.deleteEntry=function(entry) {53};54molmil.UI.prototype.displayEntry=function(entry, dm) {55 if (entry.ref) molmil.displayEntry(entry.ref, dm, true, this.soup);56 document.body.onmousedown();57};58molmil.UI.prototype.editLabel=function(settings) {59 var obj=null, text;60 61 var onOK = null;62 63 if (settings instanceof molmil.labelObject) {64 obj = settings;65 settings = obj.settings;66 text = obj.text;67 68 onOK = function(infoBox) {69 var settings = {};70 settings.color = molmil.hex2rgb(infoBox.color.value);71 settings.fontSize = parseFloat(infoBox.fontSize.value);72 settings.dx = parseFloat(infoBox.dx.value) || 0.0; settings.dy = parseFloat(infoBox.dy.value) || 0.0; settings.dz = parseFloat(infoBox.dz.value) || 0.0;73 settings.xyz = infoBox.xyz;74 molmil.addLabel(infoBox.text.value, settings, obj);75 };76 }77 else {78 text = settings.text;79 settings.dx = settings.dx || 0.0; settings.dy = settings.dy || 0.0; settings.dz = settings.dz || 0.0;80 settings.fontSize = settings.fontSize || 20;81 settings.color = settings.color || [0, 255, 0];82 onOK = function(infoBox) {83 var settings = {};84 settings.color = molmil.hex2rgb(infoBox.color.value);85 settings.fontSize = parseFloat(infoBox.fontSize.value);86 settings.dx = parseFloat(infoBox.dx.value) || 0.0; settings.dy = parseFloat(infoBox.dy.value) || 0.0; settings.dz = parseFloat(infoBox.dz.value) || 0.0;87 settings.xyz = infoBox.xyz;88 molmil.addLabel(infoBox.text.value, infoBox.settings, infoBox.soup);89 };90 }91 92 this.popupMenuBuilder("Label", [93 ["Text:", "text", "text", settings.text], 94 ["Color:", "color", "color", settings.color],95 ["Font-size:", "fontSize", "text", settings.fontSize],96 ["Offset-x:", "dx", "text", settings.dx],97 ["Offset-y:", "dy", "text", settings.dy],98 ["Offset-z:", "dz", "text", settings.dz],99 ["", "settings", "hidden", settings],100 ["", "soup", "hidden", this.soup]101 ], onOK);102};103molmil.UI.prototype.showContextMenuAtom=function(x, y, pageX) {104 if (document.body.onmousedown) document.body.onmousedown();105 106 var atoms = this.soup.atomSelection;107 if (! atoms.length) return;108 this.complexMenu.position = [x, y, pageX];109 var title = "";110 if (atoms.length > 1){111 title = this.soup.atomSelection.length+" atoms selected";112 }113 else {114 var atom = atoms[0];115 var sgl = atom.molecule.atoms.length > 1;116 title = (sgl ? atom.atomName : atom.element) + " - " + (sgl ? (atom.molecule.name || "") + " " : "") + (atom.molecule.RSID || "") + ( atom.chain.name ? " - Chain " + atom.chain.name : "") + " - " + atom.chain.entry.meta.idnr + (atom.customText ? " - "+atom.customText : "");117 }118 this.buildComplexMenu(title, this.contextMenuCanvas, null, atoms);119};120molmil.setOnContextMenu = function (obj, func, lefttoo) {121 obj.oncontextmenu = func;122 if (lefttoo) obj.onclick = func;123 obj.addEventListener("touchstart", molmil.handle_contextMenu_touchStart, false);124 obj.addEventListener("touchend", molmil.handle_contextMenu_touchEnd, false);125}126molmil.UI.prototype.showRM=function(icon, reset) {127 var menu = icon.parentNode.menu;128 molmil_dep.Clear(menu);menu.innerHTML = "";129 if (menu.style.display == "none" || reset) {130 icon.innerHTML = "><br/>><br/>>";131 menu.style.maxHeight = ((this.canvas ? this.canvas : document.body)-32)+"px";132 menu.style.display = "";133 }134 else {135 icon.innerHTML = "<<br/><<br/><";136 menu.style.display = "none";137 }138 139 var files = this.canvas ? this.canvas.molmilViewer.structures : [];140 if (menu.childNodes.length > 0) {141 if (files.length == menu.nof) return;142 }143 144 menu.nof = files.length;145 menu.pushNode("span", "Structures:").className = "optCat_k";146 var options = menu.pushNode("span", "⛬"); options.UI = this;147 molmil.setOnContextMenu(options, function(e) {148 this.UI.complexMenu.position = [e.clientX, e.clientY, e.pageX];149 this.UI.buildComplexMenu("Options", this.UI.contextMenuStructuresMenu, null, this.UI.soup);150 return false;151 }, true);152 menu.pushNode("hr");153 var model, item, file;154 for (var i=0; i<files.length; i++) {155 file = files[i];156 if (file instanceof molmil.entryObject) {157 item = menu.pushNode("div");158 item.className = "UI_entryItem";159 item.plus = item.pushNode("a", "+");160 item.plus.className = "optCat_p";161 item.name = item.pushNode("a", file.meta.id + " ("+file.meta.idnr+")");162 item.name.title = "Left click to expand\nRight click to show the context menu for display & color options";163 item.name.className = "optCat_n";164 item.style.color = file.display ? "" : "lightgrey"165 item.plus.onclick = item.name.onclick = function(ev) {166 if (ev.ctrlKey) {167 if (this.parentNode.payload[0].display) {168 molmil.displayEntry(this.parentNode.payload, molmil.displayMode_None, true, this.UI.soup);169 this.parentNode.style.color = "lightgrey";170 }171 else {172 molmil.displayEntry(this.parentNode.payload, molmil.displayMode_Visible, true, this.UI.soup);173 this.parentNode.style.color = "";174 }175 }176 else molmil_dep.expandCatTree.apply(this, []);177 }178 item.name.UI = item.UI = this;179 molmil.setOnContextMenu(item.name, function(e) {180 this.UI.complexMenu.position = [e.clientX, e.clientY, e.pageX];181 this.UI.buildComplexMenu(this.parentNode.payload[0].meta.id, this.UI.contextMenuStructuresEntry, null, this.parentNode.payload);182 return false;183 });184 185 item.name.mtype = 1;186 item.payload = item.name.ref = [file];187 item.expandFunc = this.showChains;188 }189 else {190 item = menu.pushNode("div", file.meta.filename + (file.meta.idnr ? " ("+file.meta.idnr+")" : ""));191 // if item.options.length > 1 => show menu to select sub-components (e.g. mpbf large structures)192 193 item.className = "optCat_n";194 item.style.marginLeft = "1.25em";195 item.UI = this;196 molmil.setOnContextMenu(item, function(e) {197 this.UI.complexMenu.position = [e.clientX, e.clientY, e.pageX];198 this.UI.buildComplexMenu(this.ref[0].meta.id, this.ref[0].meta.mode == "general" ? this.UI.contextMenuVRML : this.UI.contextMenuIsosurfaceEntry, null, this.ref);199 return false;200 }); // TODO201 item.mtype = 10;202 item.ref = [file];203 }204 }205 206 menu.pushNode("hr");207 menu.pushNode("span", "Labels:").className = "optCat_k";;208 menu.pushNode("hr");209 210 var labels = this.canvas ? this.canvas.molmilViewer.texturedBillBoards : [];211 for (var i=0; i<labels.length; i++) {212 item = menu.pushNode("div", labels[i].text);213 item.className = "optCat_n";214 item.style.marginLeft = "1.25em";215 item.UI = this; item.label = labels[i];216 molmil.setOnContextMenu(item, function(e) {217 this.UI.complexMenu.position = [e.clientX, e.clientY, e.pageX];218 this.UI.buildComplexMenu(this.innerHTML, this.UI.contextMenuLabel, null, this.label);219 return false;220 });221 }222};223molmil.UI.prototype.showChains=function(target, payload) {224 var chain, item;225 target.pushNode("span", "Chains:").className = "optCat_k";226 target.pushNode("hr");227 payload = payload instanceof Array ? payload[0] : payload;228 for (var i=0; i<payload.chains.length; i++) {229 chain = payload.chains[i];230 item = target.pushNode("div");231 item.plus = item.pushNode("a", "+");232 item.plus.className = "optCat_p";233 var saa = chain.name ? chain.name : i+1;234 if (chain.authName && chain.authName != saa) saa += " ("+chain.authName+")";235 item.name = item.pushNode("a", saa);236 item.name.title = "Left click to expand\nRight click to show the context menu for display & color options";237 item.name.className = "optCat_n";238 if (chain.display) item.style.color = "";239 item.style.color = chain.display ? "" : "lightgrey"240 item.plus.onclick = item.name.onclick = function(ev) {241 if (ev.ctrlKey) {242 if (this.parentNode.payload.display) {243 molmil.displayEntry(this.parentNode.payload, molmil.displayMode_None, true, this.UI.soup);244 this.parentNode.style.color = "lightgrey";245 }246 else {247 molmil.displayEntry(this.parentNode.payload, molmil.displayMode_Visible, true, this.UI.soup);248 this.parentNode.style.color = "";249 }250 }251 else molmil_dep.expandCatTree.apply(this, []);252 }253 item.payload = chain;254 item.name.UI = item.UI = this.UI;255 item.expandFunc = this.UI.showResidues;256 molmil.setOnContextMenu(item.name, function(e) {257 this.UI.complexMenu.position = [e.clientX, e.clientY, e.pageX];258 this.UI.buildComplexMenu(this.parentNode.payload, this.UI.contextMenuStructuresChain, null, this.parentNode.payload);259 return false;260 });261 item.name.mtype = 2;262 item.name.ref = [chain];263 }264 target.pushNode("hr");265};266molmil.UI.prototype.showResidues=function(target, payload) {267 target.pushNode("span", "Residues/Ligands:").className = "optCat_k";;268 target.pushNode("hr");269 var mol, item;270 payload = payload instanceof Array ? payload[0] : payload;271 for (var i=0; i<payload.molecules.length; i++) {272 mol = payload.molecules[i];273 item = target.pushNode("div", mol.name+(mol.RSID ? " ("+mol.RSID+")" : ""));274 item.title = "Double click to jump to residue\nRight click to show the context menu for display & color options";275 item.className = "optCat_n";276 item.payload = mol; item.UI = this.UI;277 if (this.UI.molSelection.indexOf(mol) != -1) item.style.fontWeight = "bold";278 this.UI.molRef[mol.MID] = item;279 molmil.setOnContextMenu(item, function(e) {280 this.onclick(e, true);281 this.UI.complexMenu.position = [e.clientX, e.clientY, e.pageX];282 this.UI.buildComplexMenu(this.payload, this.UI.contextMenuStructuresResidue, null, this.UI.molSelection);283 return false;284 });285 item.mtype = 3;286 item.ref = [mol];287 item.ondblclick = function() {288 this.UI.canvas.molmilViewer.gotoMol(this.payload);289 };290 item.onclick = function(e, passThrough) {291 if (e.detail > 1) return;292 if (passThrough && this.UI.molSelection.indexOf(this.payload) != -1) return;293 if (e.altKey) {294 var idx = this.UI.canvas.molmilViewer.atomSelection.indexOf(this.payload.CA || this.payload.atoms[0]);295 if (idx == -1) this.UI.canvas.molmilViewer.atomSelection.push(this.payload.CA || this.payload.atoms[0]);296 else this.UI.canvas.molmilViewer.atomSelection.splice(idx, 1);297 298 var idx = this.UI.molSelection.indexOf(this.payload);299 if (idx == -1) {this.UI.molSelection.push(this.payload); this.style.fontWeight = "bold";}300 else {this.UI.molSelection.splice(idx, 1); this.style.fontWeight = "";}301 }302 else if (e.shiftKey) { // check 303 if (this.UI.molSelection.length) {304 // figure out all the residues in between and mark those...305 var lastMID = this.UI.molSelection[this.UI.molSelection.length-1].MID306 var currMID = this.payload.MID;307 if (lastMID > currMID) {var tmp = lastMID; lastMID = currMID; currMID = tmp;}308 var i, tmp;309 for (i=lastMID; i<=currMID; i++) {310 tmp = this.UI.molRef[i];311 if (! tmp || this.UI.molSelection.indexOf(tmp.payload) != -1) continue;312 this.UI.molSelection.push(tmp.payload); 313 tmp.style.fontWeight = "bold";314 }315 }316 else {this.UI.molSelection = [this.payload]; this.style.fontWeight = "bold";}317 }318 else {319 if (this.UI.molSelection.length == 1 && this.UI.molSelection[0] == this.payload) {320 this.UI.molSelection = [];321 this.style.fontWeight = "";322 this.UI.canvas.molmilViewer.atomSelection = [];323 }324 else {325 this.UI.canvas.molmilViewer.atomSelection = [this.payload.CA || this.payload.atoms[0]];326 for (var i=0; i<this.UI.molSelection.length; i++) this.UI.molRef[this.UI.molSelection[i].MID].style.fontWeight = "";327 this.UI.molSelection = [this.payload];328 this.style.fontWeight = "bold";329 }330 }331 this.UI.canvas.renderer.updateSelection();332 this.UI.canvas.update = true;333 };334 }335 target.pushNode("hr");336};337// add a new File IO handler, because the current list is getting too long (and it still doesn't include everything...)338//molmil.UI.prototype.339molmil.UI.prototype.showLM=function(icon) {340 var UI = this;341 if (! molmil.VRstatus) return molmil.initVR(null, function() {UI.showLM(icon);});342 343 try {344 if (icon.parentNode.childNodes.length > 1) {345 icon.parentNode.removeChild(icon.nextSibling); icon.parentNode.removeChild(icon.nextSibling); 346 if (this.onLMhide) this.onLMhide();347 return;348 }349 }350 catch (e) {}351 352 var menu = document.createElement("div"), e;353 menu.className = "molmil_UI_LM";354 e = menu.appendChild(document.createElement("div")); e.menu = menu; e.UI = this;355 e.className = "molmil_UI_ME";356 e.innerHTML = "Open >";357 e.title = "Open files or entries";358 e.onclick = function() {359 molmil_dep.Clear(this.menu.sub);360 var e;361 this.menu.sub.style.display = "";362 if (! molmil_dep.dBT.ios_version) {363 e = this.menu.sub.pushNode("div", "mmCIF file", "molmil_UI_ME");364 e.UI = this.UI;365 e.onclick = function() {this.UI.open("mmCIF", 2);};366 e = this.menu.sub.pushNode("div", "PDBML file", "molmil_UI_ME");367 e.UI = this.UI;368 e.onclick = function() {this.UI.open("PDBML", 3);};369 e = this.menu.sub.pushNode("div", "mmJSON file", "molmil_UI_ME");370 e.UI = this.UI;371 e.onclick = function() {this.UI.open("mmJSON", 1);};372 e = this.menu.sub.pushNode("div", "PDB (flat) file", "molmil_UI_ME");373 e.UI = this.UI;374 e.onclick = function() {this.UI.open("PDB", 4);};375 e = this.menu.sub.pushNode("div", "GRO file", "molmil_UI_ME");376 e.UI = this.UI;377 e.onclick = function() {this.UI.open("GRO", 7);};378 e = this.menu.sub.pushNode("div", "CCP4 file", "molmil_UI_ME");379 e.UI = this.UI;380 e.onclick = function() {this.UI.open("CCP4", "ccp4", null, null, true);};381 e = this.menu.sub.pushNode("div", "MDL mol file", "molmil_UI_ME");382 e.UI = this.UI;383 e.onclick = function() {this.UI.open("MDL mol", "mdl");};384 e = this.menu.sub.pushNode("div", "Mol2 file", "molmil_UI_ME");385 e.UI = this.UI;386 e.onclick = function() {this.UI.open("Mol2", "mol2");};387 e = this.menu.sub.pushNode("div", "Polygon XML file", "molmil_UI_ME");388 e.UI = this.UI;389 e.onclick = function() {this.UI.open("Polygon XML file", 5);};390 e = this.menu.sub.pushNode("div", "Polygon JSON file", "molmil_UI_ME");391 e.UI = this.UI;392 e.onclick = function() {this.UI.open("Polygon JSON file", 6);};393 this.menu.sub.pushNode("hr");394 }395 e = this.menu.sub.pushNode("div", "PDB (PDBj)", "molmil_UI_ME");396 e.UI = this.UI;397 e.onclick = function() {this.UI.openID(1);};398 e = this.menu.sub.pushNode("div", "PDB chem_comp (PDBj)", "molmil_UI_ME");399 e.UI = this.UI;400 e.onclick = function() {this.UI.openID(2);};401 };402 e = menu.appendChild(document.createElement("div")); e.menu = menu; e.UI = this;403 e.className = "molmil_UI_ME";404 e.innerHTML = "Save >";405 e.onclick = function() {406 molmil_dep.Clear(this.menu.sub);407 var e;408 this.menu.sub.style.display = "";409 e = this.menu.sub.pushNode("div", "PNG image", "molmil_UI_ME");410 e.UI = this.UI;411 e.onclick = function() {this.UI.savePNG();};412 413 e = this.menu.sub.pushNode("div", "MP4 video", "molmil_UI_ME");414 e.UI = this.UI;415 e.onclick = function() {molmil.initVideo(this.UI);};416 e = this.menu.sub.pushNode("div", "PLY polygon file", "molmil_UI_ME");417 e.UI = this.UI;418 e.onclick = function() {molmil.exportPLY(this.UI.soup);};419 420 e = this.menu.sub.pushNode("div", "STL polygon file", "molmil_UI_ME");421 e.UI = this.UI;422 e.onclick = function() {molmil.exportSTL(this.UI.soup);};423 424 e = this.menu.sub.pushNode("div", "MPBF polygon file", "molmil_UI_ME");425 e.UI = this.UI;426 e.onclick = function() {molmil.exportMPBF(this.UI.soup);};427 };428 429 430 menu.pushNode("hr");431 432 e = menu.appendChild(document.createElement("div")); e.UI = this; e.LM = icon;433 e.className = "molmil_UI_ME";434 e.innerHTML = "Style IF";435 e.title = "Opens Molmil's styling interface";436 e.onclick = function() {this.LM.onclick(); UI.styleif("structure");};437 438 e = menu.appendChild(document.createElement("div")); e.UI = this; e.LM = icon;439 e.className = "molmil_UI_ME";440 e.innerHTML = "Settings";441 e.title = "Opens Molmil's advanced settings panel";442 e.onclick = function() {this.LM.onclick(); UI.styleif("settings");};443 444 var number_of_frames = this.soup.structures.length ? this.soup.structures[0].number_of_frames : 0;445 446 if (number_of_frames > 1) {447 e = menu.appendChild(document.createElement("div")); e.menu = menu; e.UI = this;448 e.className = "molmil_UI_ME";449 e.innerHTML = "Animation";450 e.canvas = this.canvas; e.LM = icon;451 e.title = "Displays Animation panel, useful for exploring multiple models or playing MD trajectories";452 e.onclick = function() {453 this.UI.animationPopUp();454 this.LM.onclick();455 };456 menu.pushNode("hr");457 }458 459 if (! molmil_dep.dBT.ios_version) {460 e = menu.pushNode("div");461 e.className = "molmil_UI_ME";462 e.innerHTML = "Enable full-screen";463 e.canvas = this.canvas; e.LM = icon;464 e.title = "Enables full screen mode";465 e.onclick = function() {466 var cc = this.canvas.parentNode;467 var rfs = cc.requestFullScreen || cc.webkitRequestFullScreen || cc.mozRequestFullScreen || cc.msRequestFullscreen || null;468 if (rfs) rfs.call(cc);469 this.LM.onclick();470 };471 }472 if (molmil.vrDisplays && molmil.vrDisplays.length) {473 e = menu.pushNode("div");474 e.className = "molmil_UI_ME";475 e.innerHTML = "Enable WebVR";476 e.canvas = this.canvas; e.LM = icon;477 e.title = "Enables Virtual Reality mode";478 e.onclick = function() {479 molmil.initVR(this.canvas.molmilViewer);480 this.LM.onclick();481 };482 }483 e = menu.appendChild(document.createElement("div")); e.UI = this;484 e.className = "molmil_UI_ME";485 e.innerHTML = "Toggle CLI";486 e.title = "Toggles between displaying and hiding the Command Line Interface";487 e.onclick = function() {this.UI.toggleCLI();};488 489 e = menu.appendChild(document.createElement("div")); e.UI = this;490 e.className = "molmil_UI_ME";491 e.innerHTML = "Clear";492 e.title = "Removes all loaded entries from this canvas";493 e.onclick = function() {this.UI.clear();};494 495 menu.pushNode("hr");496 497 e = menu.appendChild(document.createElement("div")); e.UI = this;498 e.className = "molmil_UI_ME";499 e.innerHTML = "Help"; e.LM = icon;500 e.onclick = function() {window.open("https://github.com/gjbekker/molmil/wiki"); this.LM.onclick();};501 502 e = menu.appendChild(document.createElement("div")); e.UI = this;503 e.className = "molmil_UI_ME";504 e.innerHTML = "Manual"; e.LM = icon;505 e.onclick = function() {window.open(molmil.settings.src+"manual.html"); this.LM.onclick();};506 507 e = menu.appendChild(document.createElement("div")); e.UI = this;508 e.className = "molmil_UI_ME";509 e.innerHTML = "Paper"; e.LM = icon;510 e.onclick = function() {window.open("https://doi.org/10.1186/s13321-016-0155-1"); this.LM.onclick();};511 icon.parentNode.appendChild(menu);512 menu.sub = icon.parentNode.appendChild(document.createElement("div"));513 menu.sub.className = "molmil_UI_LM";514 menu.sub.style.display = "none";515 516 if (this.onLMshow) this.onLMshow();517};518molmil.UI.prototype.view=function(sub) {519 molmil_dep.Clear(sub);520 var e, UI = this;521 sub.style.display = "";522 e = sub.pushNode("div", "Reset zoom", "molmil_UI_ME");523 e.onclick = function() {524 if (UI.LM && UI.LM.parentNode.childNodes.length > 1) UI.LM.onclick();525 UI.soup.renderer.camera.z = UI.soup.calcZ();526 UI.soup.canvas.update = true;527 };528 529 if (! this.soup.AisB) {530 e = sub.pushNode("div", "Configure BU", "molmil_UI_ME");531 e.onclick = function() {532 UI.styleif("bu");533 if (UI.LM && UI.LM.parentNode.childNodes.length > 1) UI.LM.onclick();534 if (UI.onLMshow) UI.onLMshow();535 };536 }537}538molmil.UI.prototype.toggleWaters=function(show) {539 this.soup.waterToggle(show);540 this.soup.renderer.initBuffers();541 this.soup.canvas.update = true;542 document.body.onmousedown();543};544molmil.UI.prototype.toggleHydrogens=function(show) {545 this.soup.hydrogenToggle(show);546 this.soup.renderer.initBuffers();547 this.soup.canvas.update = true;548 document.body.onmousedown();549};550molmil.UI.prototype.animationPopUp=function() {551 var popup = molmil_dep.dcE("div");552 popup.setClass("molmil_menu_popup");553 554 popup.pushNode("div", "Animation controls");555 popup.pushNode("hr");556 557 this.soup.animation.initialise(popup);558 if (this.soup.frameInfo) {559 var slider = popup.pushNode("input");560 slider.type = "range";561 slider.value = this.soup.animation.frameNo;562 slider.min = 0;563 slider.max = this.soup.frameInfo.length-1;564 slider.soup = this.soup;565 slider.oninput = function(e) {this.soup.animation.go2Frame(parseInt(this.value));};566 popup.sliderBox = slider;567 var timeBox = popup.pushNode("span", this.soup.frameInfo[0][1].toFixed(1)+"ps");568 popup.timeBox = timeBox;569 }570 else {571 var slider = popup.pushNode("input");572 slider.type = "range";573 slider.value = this.soup.animation.frameNo;574 slider.min = 0;575 slider.max = this.soup.chains[0].modelsXYZ.length-1;576 slider.soup = this.soup;577 slider.oninput = function(e) {this.soup.animation.go2Frame(parseInt(this.value));};578 popup.sliderBox = slider;579 var timeBox = popup.pushNode("span", "0");580 popup.timeBox = timeBox;581 }582 this.soup.animation.updateInfoBox();583 584 popup.pushNode("br");585 586 popup.pushNode("span", "Motion:");587 588 label = popup.pushNode("label");589 inp = label.pushNode("input"); inp.type = "radio"; inp.name = "motion"; if (this.soup.animation.motionMode == 1) inp.checked = true;590 label.pushNode("span", "Forward");591 label.AI = this.soup.animation;592 label.onclick = function() {this.AI.motionMode = 1;};593 594 label = popup.pushNode("label");595 inp = label.pushNode("input"); inp.type = "radio"; inp.name = "motion"; if (this.soup.animation.motionMode == 2) inp.checked = true;596 label.pushNode("span", "Backward");597 label.AI = this.soup.animation;598 label.onclick = function() {this.AI.motionMode = 2;};599 600 label = popup.pushNode("label");601 inp = label.pushNode("input"); inp.type = "radio"; inp.name = "motion"; if (this.soup.animation.motionMode == 3) inp.checked = true;602 label.pushNode("span", "Swing");603 label.AI = this.soup.animation;604 label.onclick = function() {this.AI.motionMode = 3;};605 606 popup.pushNode("br");607 608 label = popup.pushNode("div"); label.setClass("unselectableText"); label.style.fontStyle = "normal"; label.style.textAlign = "center";609 inp = label.pushNode("span", "|⋘"); inp.setClass("smallButton");610 inp.AI = this.soup.animation;611 inp.onclick = function() {this.AI.beginning();}612 613 inp = label.pushNode("span", "<"); inp.setClass("smallButton");614 inp.AI = this.soup.animation;615 inp.onclick = function() {this.AI.previous();}616 617 inp = label.pushNode("span", "ll"); inp.setClass("smallButton");618 inp.AI = this.soup.animation;619 inp.onclick = function() {this.AI.pause();}620 621 inp = label.pushNode("span", "►"); inp.setClass("smallButton");622 inp.AI = this.soup.animation;623 inp.onclick = function() {this.AI.play();}624 625 inp = label.pushNode("span", ">"); inp.setClass("smallButton");626 inp.AI = this.soup.animation;627 inp.onclick = function() {this.AI.next();}628 629 inp = label.pushNode("span", "⋙|"); inp.setClass("smallButton");630 inp.AI = this.soup.animation;631 inp.onclick = function() {this.AI.end();}632 633 634 popup.close = popup.pushNode("button", "Close"); popup.close.style.display = "block"; popup.close.style.marginLeft = popup.close.style.marginRight = "auto";635 popup.close.onclick = function() {this.popup.parentNode.removeChild(this.popup);};636 popup.close.popup = popup;637 638 this.LM.parentNode.pushNode(popup);639 640 641 // animation popup...642 // forward, backward, both643 // repeat644 // beginning, previous, pause, play, next, end buttons645}646molmil.UI.prototype.resetRM=function() {647 try {648 molmil_dep.Clear(this.RM.parentNode.menu);649 if (this.RM.parentNode.menu.style.display != "none") this.showRM(this.RM, true);650 }651 catch (e) {}652};653molmil.UI.prototype.toggleCLI=function() {654 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();655 656 if (! this.canvas.commandLine) new molmil.commandLine(this.canvas);657 this.canvas.commandLine.icon.onclick();658 this.resetRM();659};660molmil.UI.prototype.clear=function() {661 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();662 663 var popup = molmil_dep.dcE("div");664 popup.setClass("molmil_menu_popup");665 666 popup.pushNode("div", "Do you want to clear all loaded structures?");667 popup.yes = popup.pushNode("button", "Yes"); popup.yes.canvas = this.canvas; popup.yes.UI = this;668 popup.yes.onclick = function() {669 if (this.canvas) molmil.clear(this.canvas);670 this.UI.resetRM();671 popup.cancel.onclick();672 };673 popup.cancel = popup.pushNode("button", "Cancel");674 popup.cancel.onclick = function() {this.popup.parentNode.removeChild(this.popup);};675 popup.cancel.popup = popup;676 677 this.LM.parentNode.pushNode(popup);678};679molmil.UI.prototype.showDialog=function(func) {680 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();681 682 var popup = molmil_dep.dcE("div");683 popup.setClass("molmil_menu_popup");684 685 if (func) func.apply(this, [popup]);686 687 if (this.LM) this.LM.parentNode.pushNode(popup);688 689 return popup;690}691molmil.UI.prototype.xyz_input_popup=function(fp, fn, cb) {692 this.showDialog(function(dialog) {693 var table = dialog.pushNode("table"), tr, td, load, cancel;694 var skipBonds;695 tr = table.pushNode("tr");696 tr.pushNode("td", "Filename:");697 tr.pushNode("td", fn);698 699 tr = table.pushNode("tr");700 tr.pushNode("td", "Skip bond building:");701 skipBonds = tr.pushNode("td").pushNode("input");702 skipBonds.type = "checkbox";703 704 load = dialog.pushNode("button", "Load");705 load.onclick = function() {706 var settings = {};707 708 settings.skipBonds = skipBonds.checked;709 this.UI.soup.loadStructureData(fp, "xyz", fn, cb, settings);710 711 dialog.parentNode.removeChild(dialog);712 }713 load.UI = this;714 cancel = dialog.pushNode("button", "Cancel");715 cancel.onclick = function() {dialog.parentNode.removeChild(dialog);};716 717 });718}719molmil.UI.prototype.ccp4_input_popup=function(fp, fn, cb) {720 this.showDialog(function(dialog) {721 var table = dialog.pushNode("table"), tr, td, load, cancel;722 var sigma, solid, skipnorm;723 tr = table.pushNode("tr");724 tr.pushNode("td", "Filename:");725 tr.pushNode("td", fn);726 727 tr = table.pushNode("tr");728 tr.pushNode("td", "Sigma:");729 sigma = tr.pushNode("td").pushNode("input");730 sigma.value = 1.0;731 732 tr = table.pushNode("tr");733 tr.pushNode("td", "Solid:");734 solid = tr.pushNode("td").pushNode("input");735 solid.type = "checkbox";736 solid.checked = true;737 738 tr = table.pushNode("tr");739 tr.pushNode("td", "Skip normalization:");740 skipnorm = tr.pushNode("td").pushNode("input");741 skipnorm.type = "checkbox";742 743 load = dialog.pushNode("button", "Load");744 load.onclick = function() {745 var settings = {};746 try {settings.sigma = parseFloat(sigma.value);}747 catch (e) {return alert("Incorrect value for sigma");}748 749 settings.solid = solid.checked;750 settings.skipNormalization = skipnorm.checked;751 this.UI.soup.loadStructureData(fp, "ccp4", fn, cb, settings);752 753 dialog.parentNode.removeChild(dialog);754 }755 load.UI = this;756 cancel = dialog.pushNode("button", "Cancel");757 cancel.onclick = function() {dialog.parentNode.removeChild(dialog);};758 759 });760}761molmil.UI.prototype.open=function(name, format, ondone, oncancel, binary) {762 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();763 if (this.onLMshow) this.onLMshow();764 765 var soup = this.soup;766 var UI = this;767 768 var popup = molmil_dep.dcE("div");769 popup.setClass("molmil_menu_popup");770 771 popup.pushNode("div", "Open "+name+" file: ");772 popup.inp = popup.pushNode("input");773 popup.inp.type = "file";774 775 popup.load = popup.pushNode("button", "Load");776 popup.load.fileFormat = format;777 popup.settings = {};778 popup.load.onclick = function() {779 if (! popup.inp.files.length) return;780 var r = new FileReader();781 r.fileFormat = this.fileFormat;782 r.filename = popup.inp.files[0].name;783 r.onload = function(e) {784 popup.cancel.onclick();785 786 var cb = function(soup, struc) {787 UI.resetRM();788 if (ondone) ondone(soup, struc);789 else {790 molmil.displayEntry(struc, soup.AID > 1e5 ? 5 : 1);791 molmil.colorEntry(struc, 1, [], true, soup);792 }793 };794 795 if (this.fileFormat == "ccp4") UI.ccp4_input_popup(e.target.result, this.filename, cb);796 else if (this.fileFormat) soup.loadStructureData(e.target.result, this.fileFormat, this.filename, cb, popup.settings);797 else ondone(this.filename, e.target.result);798 oncancel = null;799 };800 if (binary) r.readAsArrayBuffer(popup.inp.files[0]);801 else r.readAsText(popup.inp.files[0]);802 };803 popup.cancel = popup.pushNode("button", "Cancel");804 var UI = this;805 popup.cancel.onclick = function() {this.popup.parentNode.removeChild(this.popup); if (UI.onLMhide) UI.onLMhide(); if (oncancel) oncancel();};806 popup.cancel.popup = popup;807 if (this.LM) this.LM.parentNode.pushNode(popup);808 809 return popup;810 811};812molmil.UI.prototype.openID=function(dbid) {813 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();814 if (this.onLMshow) this.onLMshow();815 816 var text, url;817 818 if (dbid == 1) { // PDB819 text = "PDB ID";820 url = molmil.settings.pdb_url;821 }822 else if (dbid == 2) { // chem_comp823 text = "Comp ID";824 url = molmil.settings.comp_url;825 }826 else return;827 828 var UI = this;829 var popup = molmil_dep.dcE("div");830 popup.setClass("molmil_menu_popup");831 832 popup.pushNode("span", text+": ");833 popup.inp = popup.pushNode("input");834 popup.inp.type = "text";835 popup.inp.onkeyup = function(ev) {836 if (ev.keyCode == 13) this.load.onclick();837 else if (ev.keyCode == 27) this.cancel.onclick();838 };839 840 popup.inp.load = popup.load = popup.pushNode("button", "Load");841 popup.load.canvas = this.canvas;842 popup.load.url = url;843 popup.load.onclick = function() {844 if (! popup.inp.value) return;845 this.canvas.molmilViewer.loadStructure(this.url.replace("__ID__", popup.inp.value), 1, function(soup, struc) {846 molmil.displayEntry(struc, soup.AID > 1e5 ? 5 : 1);847 molmil.colorEntry(struc, 1, [], true, soup);848 UI.resetRM();849 });850 popup.cancel.onclick();851 };852 popup.inp.cancel = popup.cancel = popup.pushNode("button", "Cancel");853 var UI = this;854 popup.cancel.onclick = function() {this.popup.parentNode.removeChild(this.popup); if (UI.onLMhide) UI.onLMhide();};855 popup.cancel.popup = popup;856 857 this.LM.parentNode.pushNode(popup);858 859 popup.inp.focus();860}861molmil.UI.prototype.savePNG=function() {862 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();863 if (this.onLMshow) this.onLMshow();864 865 var popup = molmil_dep.dcE("div");866 popup.setClass("molmil_menu_popup");867 868 popup.pushNode("span", " ");869 popup.range = popup.pushNode("input");870 popup.range.type = "range";871 popup.range.min = "0.25";872 popup.range.max = "4";873 popup.range.step = ".25";874 popup.range.value = "1.0";875 popup.range.onmousemove = function() {this.nfo.innerHTML = (this.canvas.width*this.value)+"px x "+(this.canvas.height*this.value)+"px";};876 popup.range.nfo = popup.pushNode("span");877 popup.range.nfo.style.display = "inline-block";878 879 popup.save = popup.pushNode("button", "Save"); popup.range.canvas = popup.save.canvas = this.canvas;880 popup.save.onclick = function() {881 if (! window.saveAs) return molmil.loadPlugin(molmil.settings.src+"lib/FileSaver.js", this.onclick, this, []); 882 883 if (molmil.configBox.stereoMode != 1 && ! molmil.configBox.keepBackgroundColor) {884 var opacity = molmil.configBox.BGCOLOR[3]; molmil.configBox.BGCOLOR[3] = 0;885 }886 var mult = parseFloat(popup.range.value);887 if (mult != 1) {888 var width = this.canvas.width; var height = this.canvas.height; var opacity = molmil.configBox.BGCOLOR[3];889 // there appears to be a problem with chrome and changing the canvas w/h --> but only at very high resolutions...890 this.canvas.width *= mult; this.canvas.height *= mult; 891 this.canvas.renderer.selectDataContext(); this.canvas.renderer.resizeViewPort();892 this.canvas.update = true; this.canvas.renderer.render();893 this.canvas.toBlob(function(blob) {saveAs(blob, "image.png");});894 this.canvas.renderer.selectDefaultContext();895 this.canvas.width = width; this.canvas.height = height;896 this.canvas.renderer.resizeViewPort();897 }898 else {899 this.canvas.renderer.selectDataContext();900 this.canvas.update = true;901 this.canvas.renderer.render();902 this.canvas.toBlob(function(blob) {saveAs(blob, "image.png");});903 this.canvas.renderer.selectDefaultContext();904 }905 if (molmil.configBox.stereoMode != 1 && ! molmil.configBox.keepBackgroundColor) molmil.configBox.BGCOLOR[3] = opacity;906 this.canvas.update = true; this.canvas.renderer.render();907 908 popup.cancel.onclick();909 };910 popup.cancel = popup.pushNode("button", "Cancel");911 var UI = this;912 popup.cancel.onclick = function() {this.popup.parentNode.removeChild(this.popup); if (UI.onLMhide) UI.onLMhide();};913 popup.cancel.popup = popup;914 915 popup.range.onmousemove();916 917 this.LM.parentNode.pushNode(popup);918}919molmil.UI.prototype.videoRenderer=function(justStart) {920 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();921 922 var videoID = null;923 var pixels = null;924 925 this.canvas.renderer.onRenderFinish = function() {926 if (! videoID) return;927 if (pixels == null) pixels = new Uint8Array(this.canvas.width * this.canvas.width * 4);928 929 if (window.addFrame) addFrame(this.canvas.toDataURL());930 else {931 var req = new molmil_dep.CallRemote("POST");932 req.AddParameter("id", videoID);933 req.AddParameter("data", this.canvas.toDataURL());934 req.Send(molmil.settings.molmil_video_url+"addFrame");935 }936 937 this.canvas.renderer.gl.readPixels(0, 0, this.canvas.width, this.canvas.height, this.canvas.renderer.gl.RGBA, this.canvas.renderer.gl.UNSIGNED_BYTE, pixels);938 };939 940 var popup = molmil_dep.dcE("div");941 popup.setClass("molmil_menu_popup");942 // add handler buttons...943 944 popup.preview = popup.pushNode("button", "Play & Preview");945 popup.pushNode("br");946 popup.record = popup.pushNode("button", "Play & Record");947 popup.pushNode("br");948 949 popup.canvas = popup.preview.canvas = popup.record.canvas = this.canvas;950 popup.preview.popup = popup.record.popup = popup;951 952 popup.preview.onclick = function() {953 videoID = null;954 //canvas.renderer.selectDefaultContext();955 this.canvas.molmilViewer.animation.beginning();956 this.canvas.molmilViewer.animation.play();957 }958 959 960 popup.endVideo = function() {961 if (this.canvas.molmilViewer.animation.playing) molmil_dep.asyncStart(this.endVideo, [], this, 250);962 else {963 if (window.finalizeVideo) finalizeVideo();964 else {965 var req = new molmil_dep.CallRemote("GET");966 req.AddParameter("id", videoID);967 req.Send(molmil.settings.molmil_video_url+"deInitVideo");968 console.log(molmil.settings.molmil_video_url+"getVideo?id="+videoID);969 window.open(molmil.settings.molmil_video_url+"getVideo?id="+videoID);970 }971 videoID = null;972 }973 }974 popup.record.onclick = function() {975 // make sure that both the width & height are divisible by 2 (ffmpeg issue)976 var w = this.canvas.width, h = this.canvas.height;977 if (w%2 == 1) w--;978 if (h%2 == 1) h--;979 if (w != this.canvas.width || h != this.canvas.height) {this.canvas.width = w; this.canvas.height = h; this.canvas.renderer.resizeViewPort();}980 if (window.initVideo) {videoID = 1; initVideo(molmil.configBox.video_path, this.canvas.width, this.canvas.height, molmil.configBox.video_framerate);}981 else {982 var req = new molmil_dep.CallRemote("GET");983 req.AddParameter("w", this.canvas.width);984 req.AddParameter("h", this.canvas.height);985 req.Send(molmil.settings.molmil_video_url+"initVideo");986 videoID = req.request.responseText;987 //canvas.renderer.selectDataContext();988 }989 this.canvas.molmilViewer.animation.beginning();990 this.canvas.molmilViewer.animation.play();991 this.popup.endVideo();992 }993 994 popup.cancel = popup.pushNode("button", "Cancel");995 popup.cancel.canvas = this.canvas;996 popup.cancel.onclick = function() {997 this.canvas.molmilViewer.animation.end();998 this.popup.endVideo();999 this.popup.parentNode.removeChild(this.popup);1000 };1001 popup.cancel.popup = popup;1002 1003 this.LM.parentNode.pushNode(popup);1004 1005 if (justStart) popup.record.onclick();1006}1007// ** drag-and-drop support for various files **1008molmil.bindCanvasInputs = function(canvas) {1009 if (! canvas.molmilViewer.UI) {1010 canvas.molmilViewer.UI = new molmil.UI(canvas.molmilViewer);1011 canvas.molmilViewer.UI.init();1012 canvas.molmilViewer.animation = new molmil.animationObj(canvas.molmilViewer);1013 }1014 1015 var mjsFunc = function(canvas, fr) {1016 if (fr.filename.endsWith(".mjs")) {1017 fr.onload = function(e) {1018 canvas.commandLine.environment.scriptUrl = "";1019 canvas.commandLine.environment.console.runCommand(e.target.result.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ""));1020 }1021 fr.readAsText(fr.fileHandle);1022 return true;1023 }1024 };1025 1026 var cancelDB = function (ev) {1027 ev.preventDefault();1028 return false;1029 }1030 var nfilesproc = [0, 0, []];1031 var renderOnlyFinal = function(soup, structures) {1032 nfilesproc[0]++;1033 if (Array.isArray(structures)) nfilesproc[2] = nfilesproc[2].concat(structures)1034 else nfilesproc[2].push(structures);1035 if (nfilesproc[0] < nfilesproc[1]) return;1036 molmil.displayEntry(nfilesproc[2], 1);1037 molmil.colorEntry(nfilesproc[2], 1, null, true, soup);1038 nfilesproc[2] = [];1039 }1040 var dropDB = function (ev) {1041 ev.preventDefault();1042 processFiles(ev.dataTransfer.items, ev.dataTransfer.files);1043 return false;1044 }1045 1046 var pasteDB = function(ev) {1047 if (ev.srcElement.className.includes("molmil_UI_cl_input")) return;1048 ev.preventDefault();1049 processFiles([], ev.clipboardData.files);1050 };1051 1052 var processFiles = function(files, files2) {1053 var fr, i, j, mjsFile = null, file;1054 1055 var dict = {}, item, entry, bakacounter = 0;1056 var bakacheck = function() {1057 if (bakacounter > 0) return;1058 1059 var items = Object.keys(dict).sort(molmil_dep.naturalSort);1060 var count = items.length;1061 for (i=0; i<count; i++) {1062 if (items[i].toLowerCase().endsWith(".mjs")) {mjsFile = items[i]; break;}1063 }1064 1065 if (mjsFile != null) {1066 canvas.mjs_fileBin = {};1067 for (i=0; i<count; i++) {1068 file = dict[items[i]];1069 if (file instanceof File) {1070 fr = new FileReader();1071 fr.filename = file.name;1072 fr.fileHandle = file;1073 }1074 else fr = file;1075 canvas.mjs_fileBin[items[i]] = fr;1076 }1077 mjsFunc(canvas, canvas.mjs_fileBin[mjsFile]);1078 return false;1079 }1080 nfilesproc[1] = count;1081 for (i=0; i<count; i++) {1082 file = dict[items[i]];1083 if (file instanceof File) {1084 fr = new FileReader();1085 fr.filename = file.name;1086 fr.fileHandle = file;1087 }1088 else fr = file;1089 var ok = false;1090 1091 for (j=0; j<canvas.inputFunctions.length; j++) {1092 if (canvas.inputFunctions[j](canvas, fr)) {ok=true; break;}1093 }1094 1095 if (! ok) {1096 for (var j in molmil.formatList) {1097 if (typeof molmil.formatList[j] != "function" || ! cmd[1].endsWith(j)) continue;1098 molmil.loadFilePointer(fr, molmil.formatList[j], canvas);1099 break;1100 }1101 }1102 }1103 1104 1105 };1106 1107 var processEntry = function(item) {1108 if (item.isFile) {1109 bakacounter += 1;1110 item.file(function(baka) {1111 dict[item.fullPath.replace(/^\//, "")] = baka;1112 bakacounter -= 1;1113 bakacheck();1114 });1115 }1116 if (! item.isDirectory) return;1117 var directoryReader = item.createReader();1118 bakacounter += 1;1119 directoryReader.readEntries(function(entries) {entries.forEach(processEntry); bakacounter -= 1;});1120 };1121 1122 for (var i=0; i<files.length; i++) {1123 item = files[i];1124 if (item.kind != 'file') continue;1125 if (item.getAsEntry) entry = item.getAsEntry();1126 else if (item.webkitGetAsEntry) entry = item.webkitGetAsEntry();1127 else {dict = null; break;} // not supported1128 processEntry(entry);1129 }1130 if (dict == null || files.length == 0) {1131 var count = 0, files = [];1132 try {1133 files = files2;1134 count = files.length;1135 } catch (e) {}1136 1137 var dict = {};1138 for (i=0; i<count; i++) dict[files[i].name] = files[i];1139 bakacheck();1140 }1141 };1142 1143 1144 window.addEventListener("paste", pasteDB);1145 canvas.addEventListener("dragover", cancelDB);1146 canvas.addEventListener("dragenter", cancelDB);1147 canvas.addEventListener("drop", dropDB);1148 1149 // mjs file1150 canvas.inputFunctions.push(mjsFunc);1151 1152 // .gz file1153 canvas.inputFunctions.push(function(canvas, fr) {1154 if (fr.filename.endsWith(".gz")) {1155 if (! window.hasOwnProperty("pako")) {var obj = molmil_dep.dcE("script"); obj.src = molmil.settings.src+"lib/pako.js"; document.getElementsByTagName("head")[0].appendChild(obj);}1156 fr.onload = function(e) {1157 if (! window.hasOwnProperty("pako")) return molmil_dep.asyncStart(this.onload, [e], this, 50);1158 var fakeObj = {filename:fr.filename.substr(0, fr.filename.length-3)};1159 fakeObj.readAsText = function() {var out = pako.inflate(new Uint8Array(e.target.result), {to: "string"}); this.onload({target: {result: out}});};1160 fakeObj.readAsArrayBuffer = function() {var out = pako.inflate(new Uint8Array(e.target.result)); this.onload({target: {result: out.buffer}});};1161 for (j=0; j<canvas.inputFunctions.length; j++) {1162 if (canvas.inputFunctions[j](canvas, fakeObj)) break;1163 }1164 }1165 canvas.molmilViewer.downloadInProgress = true;1166 fr.readAsArrayBuffer(fr.fileHandle);1167 return true;1168 }1169 });1170 1171 // .zip file1172 canvas.inputFunctions.push(function(canvas, fr) {1173 if (fr.filename.endsWith(".zip")) {1174 if (! window.hasOwnProperty("unzip")) {var obj = molmil_dep.dcE("script"); obj.src = "https://unpkg.com/unzipit@1.4.0/dist/unzipit.min.js"; document.getElementsByTagName("head")[0].appendChild(obj);}1175 fr.onload = function(e) {1176 if (! window.hasOwnProperty("unzipit")) return molmil_dep.asyncStart(this.onload, [e], this, 50);1177 unzipit.unzip(e.target.result).then(function(zipfile) {1178 var files = Object.values(zipfile.entries), files2 = [];1179 for (var f=0; f<files.length; f++) {1180 if (files[f].isDirectory) continue;1181 files2.push({1182 name: files[f].name,1183 filename: files[f].name,1184 fileObj: files[f],1185 onload: function() {},1186 readAsText: function() {1187 var fobj = this;1188 this.fileObj.text().then(function(data) {fobj.onload({target: {result: data}});});1189 },1190 readAsArrayBuffer: function() {1191 var fobj = this;1192 this.fileObj.arrayBuffer().then(function(data) {fobj.onload({target: {result: data}});});1193 }1194 });1195 }1196 processFiles([], files2);1197 canvas.molmilViewer.downloadInProgress = false;1198 });1199 }1200 fr.readAsArrayBuffer(fr.fileHandle);1201 canvas.molmilViewer.downloadInProgress = true;1202 return true;1203 }1204 });1205 1206 1207 // pdb file1208 canvas.inputFunctions.push(function(canvas, fr) {1209 if (fr.filename.endsWith(".pdb") || fr.filename.endsWith(".ent")) {1210 fr.onload = function(e) {1211 canvas.molmilViewer.loadStructureData(e.target.result, 4, this.filename, renderOnlyFinal);1212 delete canvas.molmilViewer.downloadInProgress;1213 }1214 canvas.molmilViewer.downloadInProgress = true;1215 fr.readAsText(fr.fileHandle);1216 return true;1217 }1218 });1219 1220 // mmtf file1221 canvas.inputFunctions.push(function(canvas, fr) {1222 if (fr.filename.endsWith(".mmtf")) {1223 fr.onload = function(e) {1224 canvas.molmilViewer.loadStructureData(e.target.result, "mmtf", this.filename, renderOnlyFinal);1225 delete canvas.molmilViewer.downloadInProgress;1226 }1227 canvas.molmilViewer.downloadInProgress = true;1228 fr.readAsText(fr.fileHandle);1229 return true;1230 }1231 });1232 1233 // cif file1234 canvas.inputFunctions.push(function(canvas, fr) {1235 if (fr.filename.endsWith(".cif")) {1236 fr.onload = function(e) {1237 canvas.molmilViewer.loadStructureData(e.target.result, 'cif', this.filename, renderOnlyFinal);1238 delete canvas.molmilViewer.downloadInProgress;1239 }1240 canvas.molmilViewer.downloadInProgress = true;1241 fr.readAsText(fr.fileHandle);1242 return true;1243 }1244 });1245 1246 // gro file1247 canvas.inputFunctions.push(function(canvas, fr) {1248 if (fr.filename.endsWith(".gro")) {1249 fr.onload = function(e) {1250 canvas.molmilViewer.loadStructureData(e.target.result, 7, this.filename, renderOnlyFinal);1251 delete canvas.molmilViewer.downloadInProgress;1252 }1253 canvas.molmilViewer.downloadInProgress = true;1254 fr.readAsText(fr.fileHandle);1255 return true;1256 }1257 });1258 1259 // gromacs trajectory file (trr)1260 canvas.inputFunctions.push(function(canvas, fr) {1261 if (fr.filename.endsWith(".trr")) {1262 fr.onload = function(e) {1263 canvas.molmilViewer.loadStructureData(e.target.result, "gromacs-trr", this.filename, renderOnlyFinal);1264 delete canvas.molmilViewer.downloadInProgress;1265 }1266 canvas.molmilViewer.downloadInProgress = true;1267 fr.readAsArrayBuffer(fr.fileHandle);1268 return true;1269 }1270 });1271 1272 // gromacs trajectory file (xtc)1273 canvas.inputFunctions.push(function(canvas, fr) {1274 if (fr.filename.endsWith(".xtc")) {1275 fr.onload = function(e) {1276 canvas.molmilViewer.loadStructureData(e.target.result, "gromacs-xtc", this.filename, renderOnlyFinal);1277 delete canvas.molmilViewer.downloadInProgress;1278 }1279 canvas.molmilViewer.downloadInProgress = true;1280 fr.readAsArrayBuffer(fr.fileHandle);1281 return true;1282 }1283 });1284 1285 // mypresto trajectory file1286 canvas.inputFunctions.push(function(canvas, fr) {1287 if (fr.filename.endsWith(".cor") || fr.filename.endsWith(".cod")) {1288 fr.onload = function(e) {1289 canvas.molmilViewer.loadStructureData(e.target.result, "presto-traj", this.filename, renderOnlyFinal);1290 delete canvas.molmilViewer.downloadInProgress;1291 }1292 canvas.molmilViewer.downloadInProgress = true;1293 fr.readAsArrayBuffer(fr.fileHandle);1294 return true;1295 }1296 });1297 1298 // mypresto mnt file1299 canvas.inputFunctions.push(function(canvas, fr) {1300 if (fr.filename.endsWith(".mnt")) {1301 fr.onload = function(e) {1302 canvas.molmilViewer.loadStructureData(e.target.result, "presto-mnt", this.filename, renderOnlyFinal);1303 delete canvas.molmilViewer.downloadInProgress;1304 }1305 canvas.molmilViewer.downloadInProgress = true;1306 fr.readAsArrayBuffer(fr.fileHandle);1307 return true;1308 }1309 });1310 1311 // mpbf1312 canvas.inputFunctions.push(function(canvas, fr) {1313 if (fr.filename.endsWith(".mpbf")) {1314 fr.onload = function(e) {1315 canvas.molmilViewer.loadStructureData(e.target.result, 8, this.filename, renderOnlyFinal);1316 delete canvas.molmilViewer.downloadInProgress;1317 }1318 canvas.molmilViewer.downloadInProgress = true;1319 fr.readAsArrayBuffer(fr.fileHandle);1320 return true;1321 }1322 });1323 1324 // ccp41325 canvas.inputFunctions.push(function(canvas, fr) {1326 if (fr.filename.endsWith(".ccp4")) {1327 fr.onload = function(e) {1328 canvas.molmilViewer.UI.ccp4_input_popup(e.target.result, this.filename, renderOnlyFinal);1329 delete canvas.molmilViewer.downloadInProgress;1330 }1331 canvas.molmilViewer.downloadInProgress = true;1332 fr.readAsArrayBuffer(fr.fileHandle);1333 return true;1334 }1335 });1336 1337 // mdl1338 canvas.inputFunctions.push(function(canvas, fr) {1339 if (fr.filename.endsWith(".mdl") || fr.filename.endsWith(".mol") || fr.filename.endsWith(".sdf")) {1340 fr.onload = function(e) {1341 canvas.molmilViewer.loadStructureData(e.target.result, 'mdl', this.filename, renderOnlyFinal);1342 delete canvas.molmilViewer.downloadInProgress;1343 }1344 canvas.molmilViewer.downloadInProgress = true;1345 fr.readAsText(fr.fileHandle);1346 return true;1347 }1348 });1349 1350 // mol21351 canvas.inputFunctions.push(function(canvas, fr) {1352 if (fr.filename.endsWith(".mol2")) {1353 fr.onload = function(e) {1354 canvas.molmilViewer.loadStructureData(e.target.result, 'mol2', this.filename, renderOnlyFinal);1355 delete canvas.molmilViewer.downloadInProgress;1356 }1357 canvas.molmilViewer.downloadInProgress = true;1358 fr.readAsText(fr.fileHandle);1359 return true;1360 }1361 });1362 1363 // xyz1364 canvas.inputFunctions.push(function(canvas, fr) {1365 if (fr.filename.endsWith(".xyz")) {1366 fr.onload = function(e) {1367 canvas.molmilViewer.UI.xyz_input_popup(e.target.result, this.filename, renderOnlyFinal);1368 delete canvas.molmilViewer.downloadInProgress;1369 }1370 canvas.molmilViewer.downloadInProgress = true;1371 fr.readAsText(fr.fileHandle);1372 return true;1373 }1374 });1375 1376 // obj1377 canvas.inputFunctions.push(function(canvas, fr) {1378 if (fr.filename.endsWith(".obj")) {1379 fr.onload = function(e) {1380 canvas.molmilViewer.loadStructureData(e.target.result, "obj", this.filename, renderOnlyFinal);1381 delete canvas.molmilViewer.downloadInProgress;1382 }1383 canvas.molmilViewer.downloadInProgress = true;1384 fr.readAsText(fr.fileHandle);1385 return true;1386 }1387 });1388 1389 // wrl1390 canvas.inputFunctions.push(function(canvas, fr) {1391 if (fr.filename.endsWith(".wrl")) {1392 fr.onload = function(e) {1393 canvas.molmilViewer.loadStructureData(e.target.result, "wrl", this.filename, renderOnlyFinal);1394 delete canvas.molmilViewer.downloadInProgress;1395 }1396 canvas.molmilViewer.downloadInProgress = true;1397 fr.readAsText(fr.fileHandle);1398 return true;1399 }1400 });1401 1402 // efvet1403 canvas.inputFunctions.push(function(canvas, fr) {1404 if (fr.filename.endsWith(".efvet")) {1405 fr.onload = function(e) {1406 canvas.molmilViewer.loadStructureData(e.target.result, "efvet", this.filename, renderOnlyFinal);1407 delete canvas.molmilViewer.downloadInProgress;1408 }1409 canvas.molmilViewer.downloadInProgress = true;1410 fr.readAsText(fr.fileHandle);1411 return true;1412 }1413 });1414 1415};1416// ** video support **1417molmil.initVideo = function(UI) {1418 if (window.initVideo) {1419 molmil_dep.asyncStart(UI.videoRenderer, [], UI, 0);1420 return;1421 }1422 var request = new molmil_dep.CallRemote("POST");request.ASYNC = true; request.UI = UI;1423 request.OnDone = function() {1424 var jso = JSON.parse(this.request.responseText);1425 if (! jso.found) return this.OnError();1426 molmil_dep.asyncStart(this.UI.videoRenderer, [], this.UI, 0);1427 };1428 request.OnError = function() {1429 alert("The support server to construct the video could not be found...");1430 };1431 request.Send(molmil.settings.molmil_video_url+"has_molmil_video_support");1432}1433molmil.animationObj = function (soup) {1434 this.soup = soup;1435 this.renderer = soup.renderer;1436 this.frameNo = 0;1437 this.motionMode = 1;1438 this.init = false;1439 this.delay = 66;1440 this.frameAction = function() {};1441 this.detail_or = -1;1442 this.infoBox = null;1443}1444molmil.animationObj.prototype.initialise = function(infoBox) { // redo1445 this.renderer.animationMode = true;1446 this.number_of_frames = this.soup.structures.length ? this.soup.structures[0].number_of_frames : 0;1447 this.frameNo = this.renderer.modelId;1448 this.init = true;1449 this.infoBox = infoBox;1450};1451molmil.animationObj.prototype.updateInfoBox = function() {1452 if (! this.infoBox) return;1453 if (this.infoBox.timeBox) {1454 if (this.soup.frameInfo) this.infoBox.timeBox.innerHTML = this.soup.frameInfo[this.frameNo][1].toFixed(1)+" ps ("+(this.frameNo+1)+")";1455 else this.infoBox.timeBox.innerHTML = this.frameNo;1456 }1457 if (this.infoBox.sliderBox) {1458 if (this.soup.frameInfo) this.infoBox.timeBox.value = this.soup.frameInfo[this.frameNo][1];1459 else this.infoBox.timeBox.value = this.frameNo;1460 this.infoBox.sliderBox.value = this.frameNo;1461 }1462};1463molmil.animationObj.prototype.beginning = function() {1464 if (! this.init) this.initialise();1465 this.frameNo = 0;1466 this.renderer.selectFrame(this.frameNo, this.detail_or);1467 this.soup.canvas.update = true;1468 this.frameAction();1469 this.updateInfoBox();1470};1471molmil.animationObj.prototype.go2Frame = function(fid) {1472 if (! this.init) this.initialise();1473 this.frameNo = fid;1474 this.renderer.selectFrame(this.frameNo, this.detail_or);1475 this.soup.canvas.update = true;1476 this.frameAction();1477 this.updateInfoBox();1478}1479molmil.animationObj.prototype.previous = function() {1480 if (! this.init) this.initialise();1481 this.frameNo -= 1;1482 if (this.frameNo < 0) this.frameNo = 0;1483 this.renderer.selectFrame(this.frameNo, this.detail_or);1484 this.soup.canvas.update = true;1485 this.frameAction();1486 this.updateInfoBox();1487};1488molmil.animationObj.prototype.pause = function() {1489 if (this.TID) {1490 clearTimeout(this.TID);1491 this.TID = null;1492 }1493};1494molmil.animationObj.prototype.play = function() {1495 if (! this.init) this.initialise();1496 this.playing = true;1497 if (this.motionMode == 2) this.TID = molmil_dep.asyncStart(this.backwardRenderer, [], this, this.delay);1498 else this.TID = molmil_dep.asyncStart(this.forwardRenderer, [], this, this.delay);1499};1500molmil.animationObj.prototype.next = function() {1501 if (! this.init) this.initialise();1502 this.frameNo += 1;1503 //if (this.frameNo >= this.renderer.framesBuffer.length) this.frameNo = this.renderer.framesBuffer.length-1;1504 if (this.frameNo >= this.number_of_frames) this.frameNo = this.number_of_frames-1;1505 this.renderer.selectFrame(this.frameNo, this.detail_or);1506 this.soup.canvas.update = true;1507 this.frameAction();1508 this.updateInfoBox();1509};1510molmil.animationObj.prototype.end = function() {1511 if (! this.init) this.initialise();1512 //this.frameNo = this.renderer.framesBuffer.length-1;1513 this.frameNo = this.number_of_frames-1;1514 this.renderer.selectFrame(this.frameNo, this.detail_or);1515 this.soup.canvas.update = true;1516 this.frameAction();1517 this.updateInfoBox();1518};1519molmil.animationObj.prototype.forwardRenderer = function() {1520 if (this.number_of_frames < 2) return;1521 this.frameNo += 1;1522 //if (this.frameNo >= this.renderer.framesBuffer.length) {1523 if (this.frameNo >= this.number_of_frames) {1524 if (this.motionMode == 3 || this.motionMode == 3.5) {this.frameNo -= 1; return this.backwardRenderer();}1525 else this.playing = false;1526 }1527 else {1528 this.renderer.selectFrame(this.frameNo, this.detail_or);1529 this.soup.canvas.update = true;1530 this.TID = molmil_dep.asyncStart(this.forwardRenderer, [], this, this.delay);1531 this.frameAction();1532 this.updateInfoBox();1533 }1534};1535molmil.animationObj.prototype.backwardRenderer = function() {1536 if (this.number_of_frames < 2) return;1537 this.frameNo -= 1;1538 if (this.frameNo < 0) {1539 if (this.motionMode == 3) {this.frameNo += 1; return this.forwardRenderer();}1540 else this.playing = false;1541 }1542 else {1543 this.renderer.selectFrame(this.frameNo, this.detail_or);1544 this.soup.canvas.update = true;1545 this.TID = molmil_dep.asyncStart(this.backwardRenderer, [], this, this.delay);1546 this.frameAction();1547 this.updateInfoBox();1548 }1549};1550// new UI:1551// - code wise, better structured1552// - slide-based menu (no hierarchal display)1553molmil.UI.prototype.meshOptionsFunction = function(payload, lv, mode) {1554 if (! (payload instanceof Array)) payload = [payload];1555 var mesh = payload[0], UI = this;1556 if (! (mesh instanceof molmil.polygonObject)) mesh = mesh.structures[0];1557 1558 UI.styleif_mesh(mesh, {clientX: window.innerWidth*.25, clientY: window.innerHeight*.25}, {ondelete: function() {1559 UI.deleteMeshFunction(payload);1560 }});1561 1562 this.resetRM();1563};1564molmil.UI.prototype.deleteMeshFunction = function(payload, lv, mode) {1565 if (! (payload instanceof Array)) payload = [payload];1566 1567 var files = this.soup.structures;1568 1569 for (var f=0; f<payload.length; f++) {1570 var pnames = Object.keys(payload[f].programs);1571 for (var p=0; p<pnames.length; p++) this.soup.renderer.removeProgram(payload[f].programs[pnames[p]]);1572 var idx = files.indexOf(payload[f]);1573 if (idx != -1) this.soup.structures.splice(idx, 1);1574 }1575 1576 this.soup.renderer.canvas.update = true;1577 this.resetRM();1578}1579molmil.UI.prototype.displayFunction = function(payload, lv, mode) {1580 if (! (payload instanceof Array)) payload = [payload]1581 1582 if (mode == 10001) {1583 var tmp1 = [], tmp2 = [];1584 if (lv == 2) {1585 for (var i=0; i<payload.length; i++) {1586 tmp1.push(payload[i].molecule);1587 for (var j=0; j<payload[i].chain.entry.chains.length; j++) if (tmp2.indexOf(payload[i].chain.entry.chains[j]) == -1) tmp2.push(payload[i].chain.entry.chains[j]);1588 }1589 }1590 else if (lv == 3) {1591 for (var i=0; i<payload.length; i++) {1592 tmp1.push(payload[i].chain);1593 for (var j=0; j<payload[i].chain.entry.chains.length; j++) if (tmp2.indexOf(payload[i].chain.entry.chains[j]) == -1) tmp2.push(payload[i].chain.entry.chains[j]);1594 }1595 }1596 molmil.calcHbonds(tmp1, tmp2, this.soup); var tmp = [];1597 }1598 else if (mode == 10002) {1599 // display all residues within 3.5 A...1600 var tmp = [];1601 for (var i=0; i<payload.length; i++) tmp.push(payload[i].molecule);1602 1603 molmil.showNearbyResidues(tmp, 3.5, this.soup);1604 }1605 1606 // 10001 => hydrogen bonds of the selected residue (and everything)1607 // 10002 => all residues (ligands/waters) within 3.5A from the selected residue1608 1609 for (var i=0; i<payload.length; i++) {1610 if (payload[i] instanceof molmil.atomObject) {1611 if (lv == 2) payload[i] = payload[i].molecule;1612 if (lv == 3) payload[i] = payload[i].chain;1613 if (lv == 4) payload[i] = payload[i].chain.entry;1614 }1615 }1616 1617 molmil.displayEntry(payload, mode, true, this.soup);1618};1619// field: title, id, type, options...1620molmil.UI.prototype.popupMenuBuilder = function(title, fields, ondone, oncancel) {1621 var popup = molmil_dep.dcE("div"); popup.className = "molmil_popup";1622 popup.titleDIV = popup.pushNode("div", title);1623 popup.contentTable = popup.pushNode("table");1624 popup.objects = {}; popup.ondone = ondone; popup.oncancel = oncancel;1625 1626 popup.destroy = function() {this.parentNode.removeChild(this);}1627 1628 var i, field, tmp;1629 for (i=0; i<fields.length; i++) {1630 field = popup.contentTable.pushNode("tr");1631 field.nameBox = field.pushNode("td", fields[i][0]);1632 field.valueBox = field.pushNode("td");1633 if (fields[i][2] == "color") {1634 tmp = field.valueBox.pushNode("input"); tmp.type = "color";1635 if (fields[i][3]) tmp.value = molmil.rgb2hex(fields[i][3][0], fields[i][3][1], fields[i][3][2]);1636 }1637 else if (fields[i][2] == "checkbox") {1638 tmp = field.valueBox.pushNode("input"); tmp.type = "checkbox";1639 if (fields[i][3]) tmp.checked = true;1640 }1641 else if (fields[i][2] == "hidden") {1642 popup.contentTable.removeChild(field);1643 tmp = fields[i][3];1644 }1645 else {1646 tmp = field.valueBox.pushNode("input", fields[i][3] || ""); tmp.type = "text"1647 tmp.value = fields[i][3] || "";1648 }1649 popup.objects[fields[i][1]] = tmp;1650 }1651 1652 var OK = popup.pushNode("button", "OK"); OK.popup = popup;1653 OK.onclick = function() {this.popup.ondone(this.popup.objects); this.popup.destroy();};1654 var cancel = popup.pushNode("button", "Cancel"); cancel.popup = popup;1655 cancel.onclick = function() {if (this.popup.oncancel) {this.popup.oncancel(this.popup.objects);} this.popup.destroy();};1656 1657 document.documentElement.pushNode(popup);1658};1659molmil.UI.prototype.colorFunction = function(payload, lv, mode, setting) {1660 if (mode == molmil.colorEntry_Custom && ! setting) {1661 var UI = this;1662 return this.popupMenuBuilder("Color object", [["Color by:", "color", "color"], ["Color cartoon", "colorCartoon", "checkbox", true]], function(objects) {1663 var rgba = molmil.hex2rgb(objects.color.value); rgba.push(255);1664 UI.colorFunction(payload, lv, objects.colorCartoon.checked ? mode : mode+.5, rgba);1665 });1666 }1667 if (! (payload instanceof Array)) payload = [payload];1668 1669 for (var i=0; i<payload.length; i++) {1670 if (payload[i] instanceof molmil.atomObject) {1671 if (lv == 2) payload[i] = payload[i].molecule;1672 if (lv == 3) payload[i] = payload[i].chain;1673 if (lv == 4) payload[i] = payload[i].chain.entry;1674 }1675 }1676 1677 if (lv == 103) mode += .25;1678 else if (lv == 104) mode += .5;1679 molmil.colorEntry(payload, lv == 104 ? mode+.5 : mode, setting, true, this.soup);1680};1681molmil.UI.prototype.labelFunction = function(payload, lv) {1682 if (! (payload instanceof Array)) payload = [payload];1683 var objs = [], text = "";1684 1685 if (lv == 0) { // hide1686 payload[0].display = payload[0].status = false;1687 this.soup.canvas.update = true;1688 return;1689 }1690 if (lv == 1000) { // show1691 payload[0].display = true; payload[0].status = false;1692 this.soup.canvas.update = true;1693 return;1694 }1695 if (lv == 0.5) {1696 return this.editLabel(payload[0]);1697 }1698 if (lv == -1) {1699 // delete1700 return;1701 }1702 1703 if (lv == 1) { // atom1704 for (var i=0; i<payload.length; i++) {1705 if (payload[i] instanceof molmil.atomObject) objs.push(payload[i]);1706 }1707 if (objs.length == 1) text = objs[0].toString()1708 else text = objs.length+" atoms";1709 }1710 else if (lv == 2) { // residue1711 for (var i=0; i<payload.length; i++) {1712 if (payload[i] instanceof molmil.atomObject) objs.push(payload[i].molecule);1713 if (payload[i] instanceof molmil.molObject) objs.push(payload[i]);1714 }1715 if (objs.length == 1) text = objs[0].toString()1716 else text = objs.length+" residues";1717 }1718 else if (lv == 3) { // chain1719 for (var i=0; i<payload.length; i++) {1720 if (payload[i] instanceof molmil.atomObject) objs.push(payload[i].chain);1721 if (payload[i] instanceof molmil.chainObject) objs.push(payload[i]);1722 }1723 if (objs.length == 1) text = objs[0].toString()1724 else text = objs.length+" chains";1725 }1726 else if (lv == 4) { // entry1727 for (var i=0; i<payload.length; i++) {1728 if (payload[i] instanceof molmil.atomObject) objs.push(payload[i].chain.entry);1729 if (payload[i] instanceof molmil.entryObject) objs.push(payload[i]);1730 }1731 if (objs.length == 1) text = objs[0].toString()1732 else text = objs.length+" entries";1733 }1734 var info = molmil.calcCenter(objs);1735 this.editLabel({text: text, xyz: info[0], dz: info[1]+2});1736};1737molmil.UI.prototype.initMenus = function() {1738 // 1 => molmil.atomObject1739 // 2 => molmil.molObject1740 // 3 => molmil.chainObject1741 // 4 => molmil.entryObject1742 // 5 => molmil.polygonObject1743 // 6 => molmil.labelObject1744 // 102 => side-chain1745 // 103 => cartoon-component1746 // 104 => atom-component1747//return;1748 this.contextMenuCanvas = [1749 ["Display", 0, [1750 ["Residue", 0, [1751 [function(payload, structure) {1752 if (payload[0].molecule.display) {structure[3][2] = molmil.displayMode_None; return "Hidden";}1753 else {structure[3][2] = molmil.displayMode_Visible; return "Visible";}1754 }, this.displayFunction, this, [null, 2, 0]],1755 ["Amino acid", 0, [1756 ["Space fill", this.displayFunction, this, [null, 2, molmil.displayMode_Spacefill]],1757 ["Ball & stick", this.displayFunction, this, [null, 2, molmil.displayMode_BallStick]],1758 ["Stick", this.displayFunction, this, [null, 2, molmil.displayMode_Stick]],1759 ["Wireframe", this.displayFunction, this, [null, 2, molmil.displayMode_Wireframe]]1760 ]],1761 ["Sidechain", 0, [1762 ["Space fill", this.displayFunction, this, [null, 2, molmil.displayMode_Spacefill_SC]],1763 ["Ball & stick", this.displayFunction, this, [null, 2, molmil.displayMode_BallStick_SC]],1764 ["Stick", this.displayFunction, this, [null, 2, molmil.displayMode_Stick_SC]],1765 ["Wireframe", this.displayFunction, this, [null, 2, molmil.displayMode_Wireframe_SC]]1766 ]],1767 ["Hydrogen bonds", this.displayFunction, this, [null, 2, 10001]],1768 ["Nearby residues (3.5 A)", this.displayFunction, this, [null, 2, 10002]],1769 ]],1770 ["Chain", 0, [1771 [function(payload, structure) {1772 if (payload[0].chain.display) {structure[3][2] = molmil.displayMode_None; return "Hidden";}1773 else {structure[3][2] = molmil.displayMode_Visible; return "Visible";}1774 }, this.displayFunction, this, [null, 3, molmil.displayMode_None]],1775 ["Default", this.displayFunction, this, [null, 3, molmil.displayMode_Default]],1776 ["Amino acid", 0, [1777 ["Space fill", this.displayFunction, this, [null, 3, molmil.displayMode_Spacefill]],1778 ["Ball & stick", this.displayFunction, this, [null, 3, molmil.displayMode_BallStick]],1779 ["Stick", this.displayFunction, this, [null, 3, molmil.displayMode_Stick]],1780 ["Wireframe", this.displayFunction, this, [null, 3, molmil.displayMode_Wireframe]]1781 ]],1782 ["Sidechain", 0, [1783 ["Space fill", this.displayFunction, this, [null, 3, molmil.displayMode_Spacefill_SC]],1784 ["Ball & stick", this.displayFunction, this, [null, 3, molmil.displayMode_BallStick_SC]],1785 ["Stick", this.displayFunction, this, [null, 3, molmil.displayMode_Stick_SC]],1786 ["Wireframe", this.displayFunction, this, [null, 3, molmil.displayMode_Wireframe_SC]]1787 ]],1788 ["Ca trace", this.displayFunction, this, [null, 3, molmil.displayMode_CaTrace]],1789 ["Tube", this.displayFunction, this, [null, 3, molmil.displayMode_Tube]],1790 ["Cartoon", this.displayFunction, this, [null, 3, molmil.displayMode_Cartoon]],1791 ["Rocket", this.displayFunction, this, [null, 3, molmil.displayMode_CartoonRocket]],1792 ["CG Surface", this.displayFunction, this, [null, 3, molmil.displayMode_ChainSurfaceCG]],1793 ["Simple Surface", this.displayFunction, this, [null, 3, molmil.displayMode_ChainSurfaceSimple]],1794 ["Hydrogen bonds", this.displayFunction, this, [null, 3, 10001]],1795 ]]1796 ]],1797 ["Color", 0, [1798 ["Atom", 0, [1799 ["Default", this.colorFunction, this, [null, 1, molmil.colorEntry_Default]],1800 ["Structure", this.colorFunction, this, [null, 1, molmil.colorEntry_Structure]],1801 ["Atom (CPK)", this.colorFunction, this, [null, 1, molmil.colorEntry_CPK]],1802 ["Custom", this.colorFunction, this, [null, 1, molmil.colorEntry_Custom]]1803 ]],1804 ["Residue", 0, [1805 ["Default", this.colorFunction, this, [null, 2, molmil.colorEntry_Default]],1806 ["Structure", this.colorFunction, this, [null, 2, molmil.colorEntry_Structure]],1807 ["Atom (CPK)", this.colorFunction, this, [null, 2, molmil.colorEntry_CPK]],1808 ["Custom", this.colorFunction, this, [null, 2, molmil.colorEntry_Custom]]1809 ]],1810 ["Residue (cartoon)", 0, [1811 ["Structure", this.colorFunction, this, [null, 103, molmil.colorEntry_Structure]],1812 ["Custom", this.colorFunction, this, [null, 103, molmil.colorEntry_Custom]]1813 ]],1814 ["Residue (atoms)", 0, [1815 ["Atom (CPK)", this.colorFunction, this, [null, 104, molmil.colorEntry_CPK]],1816 ["Custom", this.colorFunction, this, [null, 104, molmil.colorEntry_Custom]]1817 ]],1818 ["Chain", 0, [1819 ["Default", this.colorFunction, this, [null, 3, molmil.colorEntry_Default]],1820 ["Structure", this.colorFunction, this, [null, 3, molmil.colorEntry_Structure]],1821 ["Atom (CPK)", this.colorFunction, this, [null, 3, molmil.colorEntry_CPK]],1822 ["Group", this.colorFunction, this, [null, 3, molmil.colorEntry_Group]],1823 ["ABEGO", this.colorFunction, this, [null, 3, molmil.colorEntry_ABEGO]],1824 ["Custom", this.colorFunction, this, [null, 3, molmil.colorEntry_Custom]]1825 ]],1826 ]],1827 ["Label", 0, [1828 ["Atom", this.labelFunction, this, [null, 1]],1829 ["Residue", this.labelFunction, this, [null, 2]],1830 ["Chain", this.labelFunction, this, [null, 3]]1831 ]]1832 ];1833 1834 this.contextMenuStructuresMenu = [1835 [function(payload, structure) {return payload.showWaters ? "Hide waters" : "Show waters";}, function(payload) {1836 payload.waterToggle(!payload.showWaters);1837 payload.renderer.initBuffers();1838 payload.canvas.update = true;1839 }, this, [null, 0, 0]],1840 [function(payload, structure) {return payload.showHydrogens ? "Hide hydrogens" : "Show hydrogens";}, function(payload) {1841 payload.hydrogenToggle(!payload.showHydrogens);1842 payload.renderer.initBuffers();1843 payload.canvas.update = true;1844 }, this, [null, 0, 0]],1845 ];1846 1847 this.contextMenuVRML = [1848 [function(payload, structure) {1849 if (payload[0].display) {structure[3][2] = molmil.displayMode_None; return "Hide";}1850 else {structure[3][2] = molmil.displayMode_Visible; return "Show";}1851 }, this.displayFunction, this, [null, 0, 0]]1852 ];1853 1854 this.contextMenuIsosurfaceEntry = [1855 [function(payload, structure) {1856 if (payload[0].display) {structure[3][2] = molmil.displayMode_None; return "Hide";}1857 else {structure[3][2] = molmil.displayMode_Visible; return "Show";}1858 }, this.displayFunction, this, [null, 0, 0]],1859 ["Options", this.meshOptionsFunction, this, [null, 0, 0]],1860 ["Delete", this.deleteMeshFunction, this, [null, 0, 0]]1861 ];1862 1863 this.contextMenuStructuresEntry = [1864 ["Display", 0, [1865 [function(payload, structure) {1866 if (payload instanceof Array) payload = payload[0];1867 if (payload.display) {structure[3][2] = molmil.displayMode_None; return "Hidden";}1868 else {structure[3][2] = molmil.displayMode_Visible; return "Visible";}1869 }, this.displayFunction, this, [null, 4, 0]],1870 ["Default", this.displayFunction, this, [null, 4, molmil.displayMode_Default]],1871 ["Amino acid", 0, [1872 ["Space fill", this.displayFunction, this, [null, 4, molmil.displayMode_Spacefill]],1873 ["Ball & stick", this.displayFunction, this, [null, 4, molmil.displayMode_BallStick]],1874 ["Stick", this.displayFunction, this, [null, 4, molmil.displayMode_Stick]],1875 ["Wireframe", this.displayFunction, this, [null, 4, molmil.displayMode_Wireframe]]1876 ]],1877 ["Sidechain", 0, [1878 ["Space fill", this.displayFunction, this, [null, 4, molmil.displayMode_Spacefill_SC]],1879 ["Ball & stick", this.displayFunction, this, [null, 4, molmil.displayMode_BallStick_SC]],1880 ["Stick", this.displayFunction, this, [null, 4, molmil.displayMode_Stick_SC]],1881 ["Wireframe", this.displayFunction, this, [null, 4, molmil.displayMode_Wireframe_SC]]1882 ]],1883 ["Ca trace", this.displayFunction, this, [null, 4, molmil.displayMode_CaTrace]],1884 ["Tube", this.displayFunction, this, [null, 4, molmil.displayMode_Tube]],1885 ["Cartoon", this.displayFunction, this, [null, 4, molmil.displayMode_Cartoon]],1886 ["Rocket", this.displayFunction, this, [null, 4, molmil.displayMode_CartoonRocket]],1887 ["CG Surface", this.displayFunction, this, [null, 4, molmil.displayMode_ChainSurfaceCG]],1888 ["Simple Surface", this.displayFunction, this, [null, 4, molmil.displayMode_ChainSurfaceSimple]],1889 ["Hydrogen bonds", this.displayFunction, this, [null, 4, 10001]]1890 ]],1891 ["Color", 0, [1892 ["Default", this.colorFunction, this, [null, 4, molmil.colorEntry_Default]],1893 ["Structure", this.colorFunction, this, [null, 4, molmil.colorEntry_Structure]],1894 ["Atom (CPK)", this.colorFunction, this, [null, 4, molmil.colorEntry_CPK]],1895 ["Group", this.colorFunction, this, [null, 4, molmil.colorEntry_Group]],1896 ["ABEGO", this.colorFunction, this, [null, 4, molmil.colorEntry_ABEGO]],1897 ["Chain", this.colorFunction, this, [null, 4, molmil.colorEntry_Chain]],1898 ["Chain alt", this.colorFunction, this, [null, 4, molmil.colorEntry_ChainAlt]],1899 ["Custom", this.colorFunction, this, [null, 4, molmil.colorEntry_Custom]]1900 ]],1901 ["Label", this.labelFunction, this, [null, 4]],1902 ];1903 this.contextMenuStructuresChain = [1904 ["Display", 0, [1905 [function(payload, structure) {1906 if (payload.display) {structure[3][2] = molmil.displayMode_None; return "Hidden";}1907 else {structure[3][2] = molmil.displayMode_Visible; return "Visible";}1908 }, this.displayFunction, this, [null, 3, 0]],1909 ["Default", this.displayFunction, this, [null, 3, molmil.displayMode_Default]],1910 ["Amino acid", 0, [1911 ["Space fill", this.displayFunction, this, [null, 3, molmil.displayMode_Spacefill]],1912 ["Ball & stick", this.displayFunction, this, [null, 3, molmil.displayMode_BallStick]],1913 ["Stick", this.displayFunction, this, [null, 3, molmil.displayMode_Stick]],1914 ["Wireframe", this.displayFunction, this, [null, 3, molmil.displayMode_Wireframe]]1915 ]],1916 ["Sidechain", 0, [1917 ["Space fill", this.displayFunction, this, [null, 3, molmil.displayMode_Spacefill_SC]],1918 ["Ball & stick", this.displayFunction, this, [null, 3, molmil.displayMode_BallStick_SC]],1919 ["Stick", this.displayFunction, this, [null, 3, molmil.displayMode_Stick_SC]],1920 ["Wireframe", this.displayFunction, this, [null, 3, molmil.displayMode_Wireframe_SC]]1921 ]],1922 ["Ca trace", this.displayFunction, this, [null, 3, molmil.displayMode_CaTrace]],1923 ["Tube", this.displayFunction, this, [null, 3, molmil.displayMode_Tube]],1924 ["Cartoon", this.displayFunction, this, [null, 3, molmil.displayMode_Cartoon]],1925 ["Rocket", this.displayFunction, this, [null, 3, molmil.displayMode_CartoonRocket]],1926 ["CG Surface", this.displayFunction, this, [null, 3, molmil.displayMode_ChainSurfaceCG]],1927 ["Simple Surface", this.displayFunction, this, [null, 3, molmil.displayMode_ChainSurfaceSimple]],1928 ["Hydrogen bonds", this.displayFunction, this, [null, 3, 10001]]1929 ]],1930 ["Color", 0, [1931 ["Default", this.colorFunction, this, [null, 3, molmil.colorEntry_Default]],1932 ["Structure", this.colorFunction, this, [null, 3, molmil.colorEntry_Structure]],1933 ["Atom (CPK)", this.colorFunction, this, [null, 3, molmil.colorEntry_CPK]],1934 ["Group", this.colorFunction, this, [null, 3, molmil.colorEntry_Group]],1935 ["ABEGO", this.colorFunction, this, [null, 3, molmil.colorEntry_ABEGO]],1936 ["Custom", this.colorFunction, this, [null, 3, molmil.colorEntry_Custom]]1937 ]],1938 ["Label", this.labelFunction, this, [null, 3]],1939 ];1940 this.contextMenuStructuresResidue = [1941 ["Display", 0, [1942 [function(payload, structure) {1943 if (payload instanceof Array) payload = payload[0];1944 if (payload.display) {structure[3][2] = molmil.displayMode_None; return "Hidden";}1945 else {structure[3][2] = molmil.displayMode_Visible; return "Visible";}1946 }, this.displayFunction, this, [null, 2, 0]],1947 ["Amino acid", 0, [1948 ["Space fill", this.displayFunction, this, [null, 2, molmil.displayMode_Spacefill]],1949 ["Ball & stick", this.displayFunction, this, [null, 2, molmil.displayMode_BallStick]],1950 ["Stick", this.displayFunction, this, [null, 2, molmil.displayMode_Stick]],1951 ["Wireframe", this.displayFunction, this, [null, 2, molmil.displayMode_Wireframe]]1952 ]],1953 ["Sidechain", 0, [1954 ["Space fill", this.displayFunction, this, [null, 2, molmil.displayMode_Spacefill]],1955 ["Ball & stick", this.displayFunction, this, [null, 2, molmil.displayMode_BallStick]],1956 ["Stick", this.displayFunction, this, [null, 2, molmil.displayMode_Stick]],1957 ["Wireframe", this.displayFunction, this, [null, 2, molmil.displayMode_Wireframe]]1958 ]],1959 ["Hydrogen bonds", this.displayFunction, this, [null, 2, 10001]]1960 ]],1961 ["Color", 0, [1962 ["Default", this.colorFunction, this, [null, 2, molmil.colorEntry_Default]],1963 ["Structure", this.colorFunction, this, [null, 2, molmil.colorEntry_Structure]],1964 ["Atom (CPK)", this.colorFunction, this, [null, 2, molmil.colorEntry_CPK]],1965 ["Custom", this.colorFunction, this, [null, 2, molmil.colorEntry_Custom]]1966 ]],1967 ["Label", this.labelFunction, this, [null, 2]],1968 ];1969 1970 this.contextMenuLabel = [1971 [function(payload, structure) {1972 structure[3][1] = payload.display ? 0 : 1000;1973 return payload.display ? "Hidden" : "Visible";1974 }, this.labelFunction, this, [null, 0]],1975 ["Edit", this.labelFunction, this, [null, 0.5]],1976 ["Delete", this.labelFunction, this, [null, -1]]1977 ];1978 1979 1980 // build the structure1981 1982 this.complexMenu = molmil_dep.dcE("table");1983 this.complexMenu.id = "molmil_UI_complexMenu";1984 this.complexMenu.style.display = "none";1985 1986 this.complexMenu.titleDIV = this.complexMenu.pushNode("tr").pushNode("td");1987 this.complexMenu.titleDIV.colSpan = 2;1988 var tmp = this.complexMenu.pushNode("tr");1989 this.complexMenu.previousButton = tmp.pushNode("td");1990 this.complexMenu.menuList = tmp.pushNode("td");1991 1992 document.body.appendChild(this.complexMenu);1993 1994 this.complexMenu.previousButton.UI = this;1995};1996// structure is an array of:1997// ["text", nextCall, selfObj, args]1998molmil.UI.prototype.buildComplexMenu = function(title, structure, previousCall, payload) {1999 this.complexMenu.style.display = "";2000 molmil_dep.Clear(this.complexMenu.menuList);2001 2002 if (! previousCall) {2003 // calculate correct position2004 var delta = 0;2005 var mw = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;2006 if (mw < this.complexMenu.position[2]+(molmil_dep.fontSize*15)) delta = (this.complexMenu.position[2]+(molmil_dep.fontSize*15))-mw;2007 this.complexMenu.style.left = this.complexMenu.position[0]-delta+"px";2008 this.complexMenu.style.top = this.complexMenu.position[1]+(molmil_dep.fontSize*.67)+(document.documentElement.scrollTop || 0)+"px";2009 2010 this.complexMenu.title.innerHTML = "";2011 2012 this.complexMenu.previousButton.style.visibility = "hidden";2013 this.complexMenu.previousButton.onclick = null;2014 2015 document.body.onmousedown = function(ev) {2016 var obj = document.getElementById("molmil_UI_complexMenu");2017 if (obj.contains(ev.target)) return;2018 obj.style.display = "none";2019 document.body.onmousedown = null;2020 };2021 }2022 else {2023 this.complexMenu.previousButton.style.visibility = "";2024 this.complexMenu.previousButton.onclick = function() {this.UI.buildComplexMenu.apply(this.UI, previousCall);};2025 }2026 this.complexMenu.previousButton.innerHTML = "<<br/><<br/><";2027 2028 2029 this.complexMenu.previousCall = previousCall;2030 if (title) this.complexMenu.titleDIV.innerHTML = title;2031 2032 // each item contains:2033 // - title for the item2034 // - function to call || 0 (=> next menu level)2035 // - selfObj || title for next menu2036 // - arguments || items for next menu2037 var i, item;2038 for (i=0; i<structure.length; i++) {2039 item = this.complexMenu.menuList.pushNode("div");2040 item.UI = this; item.structure = structure[i];2041 if (typeof structure[i][0] == "function") item.text = item.pushNode("span", structure[i][0].apply(this, [payload, structure[i]])); // if structure[i][0] is a function -> execute this function2042 else item.text = item.pushNode("span", structure[i][0]);2043 item.button = item.pushNode("span", structure[i][1] ? " " : ">");2044 item.onclick = function() {2045 if (! this.structure[1]) this.UI.buildComplexMenu((this.UI.complexMenu.titleDIV.innerHTML ? this.UI.complexMenu.titleDIV.innerHTML + " > " : "") + this.structure[0], this.structure[2], [title, structure, previousCall, payload], payload);2046 else {2047 this.UI.complexMenu.style.display = "none"; // external command: close the popup2048 this.structure[3][0] = payload;2049 this.structure[1].apply(this.structure[2], this.structure[3]);2050 }2051 };2052 }2053 2054 this.complexMenu.display = "";2055 2056 2057};2058molmil.UI.prototype.styleif_au = function(contentBox) {2059 var UI = this;2060 2061 contentBox.pushNode("h1", "Structure styling options");2062 contentBox.pushNode("hr");2063 2064 contentBox.pushNode("b", "Quick styling options:");2065 2066 var ul = contentBox.pushNode("div"), opt;2067 opt = ul.pushNode("button", "Group cartoon");2068 opt.onclick = function() {2069 molmil.quickModelColor("newweb-au", {do_styling: true}, UI.soup);2070 };2071 opt = ul.pushNode("button", "Group cartoon with sidechains");2072 opt.onclick = function() {2073 molmil.quickModelColor("newweb-au-sc", {do_styling: true}, UI.soup);2074 };2075 2076 opt = ul.pushNode("button", "Cartoon");2077 opt.onclick = function() {2078 molmil.quickModelColor("cartoon", {do_styling: true}, UI.soup);2079 };2080 opt = ul.pushNode("button", "Cartoon with sidechains");2081 opt.onclick = function() {2082 molmil.quickModelColor("cartoon-sc", {do_styling: true}, UI.soup);2083 };2084 2085 opt = ul.pushNode("button", "Cartoon, colored by chain");2086 opt.onclick = function() {2087 molmil.quickModelColor("cartoon-chainc", {do_styling: true}, UI.soup);2088 };2089 opt = ul.pushNode("button", "Cartoon, color by chain with sidechains");2090 opt.onclick = function() {2091 molmil.quickModelColor("cartoon-chainc-sc", {do_styling: true}, UI.soup);2092 };2093 2094 opt = ul.pushNode("button", "Sticks (CPK)");2095 opt.onclick = function() {2096 molmil.quickModelColor("sticks", {do_styling: true}, UI.soup);2097 };2098 opt = ul.pushNode("button", "Sticks (CPK), colored by chain");2099 opt.onclick = function() {2100 molmil.quickModelColor("sticks-chainc", {do_styling: true}, UI.soup);2101 };2102 2103 opt = ul.pushNode("button", "Wireframe (CPK)");2104 opt.onclick = function() {2105 molmil.quickModelColor("lines", {do_styling: true}, UI.soup);2106 };2107 opt = ul.pushNode("button", "Wireframe (CPK), colored by chain");2108 opt.onclick = function() {2109 molmil.quickModelColor("lines-chainc", {do_styling: true}, UI.soup);2110 };2111 2112 contentBox.pushNode("br");2113 2114 contentBox.pushNode("b", "Quick operations:");2115 2116 ul = contentBox.pushNode("div");2117 opt = ul.pushNode("button", "Reposition camera");2118 opt.onclick = function() {2119 UI.soup.renderer.camera.reset();2120 UI.soup.renderer.camera.z = UI.soup.calcZ();2121 UI.canvas.update = true;2122 };2123 2124 opt = ul.pushNode("button", "Orient camera to structure");2125 opt.onclick = function() {2126 molmil.orient(null, UI.soup);2127 UI.canvas.update = true;2128 };2129 2130 if (navigator.clipboard) {2131 opt = ul.pushNode("button", "Copy image to clipboard");2132 opt.onclick = function() {2133 if (molmil.configBox.stereoMode != 1 && ! molmil.configBox.keepBackgroundColor) {2134 var opacity = molmil.configBox.BGCOLOR[3]; molmil.configBox.BGCOLOR[3] = 0;2135 }2136 var canvas = molmil.fetchCanvas();2137 canvas.renderer.selectDataContext();2138 canvas.update = true;2139 canvas.renderer.render();2140 canvas.toBlob(function(blob) {2141 navigator.clipboard.write([new ClipboardItem({"image/png": blob})]);2142 console.log("Image pasted to clipboard.");2143 });2144 canvas.renderer.selectDefaultContext();2145 if (molmil.configBox.stereoMode != 1 && ! molmil.configBox.keepBackgroundColor) molmil.configBox.BGCOLOR[3] = opacity;2146 canvas.update = true; canvas.renderer.render();2147 };2148 2149 2150 opt = ul.pushNode("button", "Copy URL for current orientation to clipboard");2151 opt.onclick = function() {2152 var x = UI.soup.renderer.camera.QView[0], y = UI.soup.renderer.camera.QView[1], z = UI.soup.renderer.camera.QView[2], w = UI.soup.renderer.camera.QView[3], t0, t1, X, Y, Z;2153 2154 t0 = 2.0 * (w * x + y * z);2155 t1 = 1.0 - 2.0 * (x * x + y * y);2156 X = Math.atan2(t0, t1);2157 t2 = 2.0 * (w * y - z * x);2158 if(t2 > 1.0) t2 = 1.0;2159 else if(t2 < -1.0) t2 = -1.0;2160 Y = Math.asin(t2);2161 t3 = 2.0 * (w * z + x * y);2162 t4 = 1.0 - 2.0 * (y * y + z * z);2163 Z = Math.atan2(t3, t4);2164 2165 X *= 180/Math.PI;2166 Y *= 180/Math.PI;2167 Z *= 180/Math.PI;2168 2169 var command = window.location + "; view null; turn x, "+X+"; turn y, "+Y+"; turn z, "+Z+"; move x, "+UI.soup.renderer.camera.x+"; move y, "+UI.soup.renderer.camera.y+"; move z, "+UI.soup.renderer.camera.z+";"2170 2171 navigator.clipboard.writeText(command);2172 2173 };2174 2175 }2176 2177 contentBox.pushNode("br");2178 2179 contentBox.pushNode("span", "For more advanced styling, please use the command line (bottom of the page), the structure menu (right-side of the page) or right-click on an atom/cartoon to show a context menu with styling options. Also, see <a href=\""+molmil.settings.src+"manual.html#style-interface\" target=\"_blank\">our manual</a> or <a href=\"https://doi.org/10.1002/pro.4211\" target=\"blank\">our recent paper</a> for more information.")2180};2181molmil.UI.prototype.styleif_bu = function(contentBox, afterDL) {2182 var UI = this;2183 2184 if (! this.soup.AisB && ! molmil.figureOutAssemblyId) {2185 this.soup.downloadInProgress++;2186 return molmil.loadPlugin(molmil.settings.src+"plugins/misc.js", UI.styleif_bu, UI, [contentBox, true]);2187 }2188 if (afterDL) delete this.soup.downloadInProgress--;2189 2190 contentBox.pushNode("h1", "Biological unit styling options");2191 contentBox.pushNode("hr");2192 2193 if (this.soup.AisB) {2194 contentBox.pushNode("span", "For this entry, the biological unit corresponds to the assymetric unit.")2195 return;2196 }2197 if (! this.soup.sceneBU) {2198 var sceneBU = molmil.buCheck(molmil.figureOutAssemblyId(this.soup.pdbxData, this.soup.BUassemblies), 3, 2, null, this.soup);2199 if (sceneBU.NOC > 1 && sceneBU.isBU && (sceneBU.type == 2 || sceneBU.size > 30000)) sceneBU.displayMode = 5;2200 else sceneBU.displayMode = 3;2201 sceneBU.colorMode = 2;2202 molmil.selectBU(sceneBU.assembly_id, sceneBU.displayMode, sceneBU.colorMode, {orient: true}, this.soup.structures.slice(-1)[0], this.soup);2203 }2204 var assembly = this.soup.sceneBU.assembly_id;2205 var rm = [this.soup.sceneBU.displayMode, this.soup.sceneBU.colorMode];2206 var table = contentBox.pushNode("table"), tr, td;2207 var US, BUrm;2208 2209 tr = table.pushNode("tr");2210 td = tr.pushNode("td", "Unit selection:");2211 2212 US = tr.pushNode("td").pushNode("select");2213 2214 2215 var soup = this.soup;2216 var noc = 0, i, c, tmp;2217 for (c=0; c<soup.chains.length; c++) {if (soup.poly_asym_ids.indexOf(soup.chains[c].name) != -1) noc++;}2218 td = US.pushNode("option", "Asymmetric unit (%NOC)".replace("%NOC", noc)); td.value = -1;2219 2220 var assembly_id = -1;2221 if (Object.keys(soup.BUmatrices).length > 1 || Object.keys(soup.BUassemblies).length > 1) {2222 for (var e in soup.BUassemblies) {2223 noc = 0;2224 for (i=0; i<soup.BUassemblies[e].length; i++) {2225 tmp = 0;2226 for (c=0; c<soup.BUassemblies[e][i][1].length; c++) {if (soup.poly_asym_ids.indexOf(soup.BUassemblies[e][i][1][c]) != -1) tmp++;}2227 noc += tmp*soup.BUassemblies[e][i][0].length;2228 }2229 td = US.pushNode("option", "Biological unit %N (%NOC)".replace("%NOC", noc).replace("%N", e)); td.value = e;2230 }2231 if (assembly && (assembly == -1 || soup.BUassemblies.hasOwnProperty(assembly))) assembly_id = assembly;2232 else {2233 assembly = figureOutAssemblyId(soup.pdbxData, soup.BUassemblies);2234 if (soup.BUassemblies.hasOwnProperty(assembly)) assembly_id = assembly;2235 }2236 }2237 2238 US.value = assembly_id;2239 2240 tr = table.pushNode("tr");2241 td = tr.pushNode("td", "Unit repr.:");2242 2243 BUrm = tr.pushNode("td").pushNode("select");2244 2245 td = BUrm.pushNode("option", "Only backbone, colored by CPK"); td.value = [1, 1];2246 td = BUrm.pushNode("option", "Only backbone, colored by each asymmetric chain"); td.value = [1, 2];2247 td = BUrm.pushNode("option", "Only backbone, colored by each chain"); td.value = [1, 3];2248 td = BUrm.pushNode("option", "Only alpha carbon and phosphorus, colored by CPK"); td.value = [2, 1];2249 td = BUrm.pushNode("option", "Only alpha carbon and phosphorus, colored by each asymmetric chain"); td.value = [2, 2];2250 td = BUrm.pushNode("option", "Only alpha carbon and phosphorus, colored by each chain"); td.value = [2, 3];2251 2252 2253 td = BUrm.pushNode("option", "Tube, colored by each asymmetric chain"); td.value = [3, 2];2254 td = BUrm.pushNode("option", "Tube, colored by each chain"); td.value = [3, 3];2255 td = BUrm.pushNode("option", "Tube, colored by secondary structure"); td.value = [3, 4];2256 td = BUrm.pushNode("option", "Cartoon, colored by each asymmetric chain"); td.value = [4, 2];2257 td = BUrm.pushNode("option", "Cartoon, colored by each chain"); td.value = [4, 3];2258 td = BUrm.pushNode("option", "Cartoon, colored by secondary structure"); td.value = [4, 4];2259 td = BUrm.pushNode("option", "Rocket, colored by each asymmetric chain"); td.value = [6, 2];2260 td = BUrm.pushNode("option", "Rocket, colored by each chain"); td.value = [6, 3];2261 td = BUrm.pushNode("option", "Rocket, colored by secondary structure"); td.value = [6, 4];2262 2263 td = BUrm.pushNode("option", "Coarse surface, colored by each asymmetric chain"); td.value = [5, 2];2264 td = BUrm.pushNode("option", "Coarse surface, colored by each chain"); td.value = [5, 3];2265 2266 BUrm.value = rm;2267 2268 US.soup = BUrm.soup = soup;2269 2270 US.oninput = BUrm.oninput = function() {2271 var tmp = BUrm.value.split(",");2272 this.soup.infoBag.BU_assembly = US.value;2273 this.soup.infoBag.BU_rm = [parseInt(tmp[0]), parseInt(tmp[1])];2274 2275 molmil.toggleBU(this.soup.infoBag.BU_assembly, this.soup.infoBag.BU_rm[0], this.soup.infoBag.BU_rm[1], null, this.soup);2276 }2277 2278 tr = table.pushNode("tr");2279 2280 td = tr.pushNode("td", "Save BU as:");2281 td = tr.pushNode("td");2282 2283 var save = td.pushNode("button");2284 save.innerHTML = "mmJSON";2285 save.onclick = function() {molmil.saveBU(soup.sceneBU.assembly_id, {format: "mmjson"}, null, soup);};2286 2287 save = td.pushNode("button");2288 save.innerHTML = "mmCIF";2289 save.onclick = function() {molmil.saveBU(soup.sceneBU.assembly_id, {format: "mmcif"}, null, soup);};2290 2291 save = td.pushNode("button");2292 save.innerHTML = "PDB";2293 save.onclick = function() {molmil.saveBU(soup.sceneBU.assembly_id, {format: "pdb"}, null, soup);};2294 2295};2296molmil.UI.prototype.drag_panel = function(title, top, left) {2297 var div = molmil_dep.dcE("div");2298 div.classList.add("dragdiv");2299 var titlediv = div.pushNode("div", title);2300 div.close = function() {this.parentNode.removeChild(this);};2301 2302 var posx, posy;2303 2304 var stopdragMe = function() {2305 document.onmouseup = molmil.handle_molmilViewer_mouseUp;2306 document.onmousemove = molmil.handle_molmilViewer_mouseMove;2307 };2308 2309 var dragMe = function(ev) {2310 ev.preventDefault();2311 2312 var dx = posx - ev.clientX;2313 var dy = posy - ev.clientY;2314 posx = ev.clientX;2315 posy = ev.clientY;2316 2317 div.style.top = (div.offsetTop - dy)+"px";2318 div.style.left = (div.offsetLeft - dx)+"px";2319 };2320 2321 titlediv.onmousedown = function(ev) {2322 ev.preventDefault();2323 posx = ev.clientX;2324 posy = ev.clientY;2325 document.onmouseup = stopdragMe;2326 document.onmousemove = dragMe;2327 };2328 div.style.top = top+"px";2329 div.style.left = left+"px";2330 2331 document.documentElement.pushNode(div);2332 2333 return div;2334}2335molmil.UI.prototype.styleif_mesh = function(mesh, ev, options) {2336 var UI = this; 2337 2338 var fname = options.filename||mesh.meta.filename;2339 if (document.getElementById("mesh_options_for_"+fname)) return;2340 2341 var div = UI.drag_panel("Mesh options for "+fname, ev.clientY+6, ev.clientX+6);2342 div.id = "mesh_options_for_"+fname;2343 2344 var settings = mesh.programs[0].settings;2345 2346 var cont, item;2347 2348 cont = div.pushNode("span");2349 item = cont.pushNode("label");2350 var wf_mode = item.pushNode(molmil_dep.createINPUT("radio", "mode", "wireframe"));2351 item.pushNode(document.createTextNode("Wireframe"));2352 if (! settings.solid) wf_mode.checked = true;2353 item.onclick = function() {2354 if (! settings.solid) return;2355 mesh.programs[0].toggleWF();2356 UI.soup.renderer.canvas.update = true;2357 transp.disabled = true;2358 }2359 item = cont.pushNode("label");2360 var solid_mode = item.pushNode(molmil_dep.createINPUT("radio", "mode", "solid"));2361 item.pushNode(document.createTextNode("Solid"));2362 if (settings.solid) solid_mode.checked = true;2363 item.onclick = function() {2364 if (settings.solid) return;2365 if (! ("alphaSet" in settings)) settings.alphaSet = 1.0;2366 mesh.programs[0].toggleWF();2367 UI.soup.renderer.canvas.update = true;2368 transp.disabled = false;2369 }2370 2371 if (settings.rgba) {2372 cont = div.pushNode("div");2373 item = cont.pushNode("input");2374 item.type = "color";2375 item.value = molmil.rgb2hex(settings.rgba[0], settings.rgba[1], settings.rgba[2]);2376 item.oninput = function() {2377 var rgb = molmil.hex2rgb(this.value);2378 settings.rgba[0] = rgb[0]; settings.rgba[1] = rgb[1]; settings.rgba[2] = rgb[2];2379 UI.soup.renderer.canvas.update = true;2380 }2381 }2382 cont = div.pushNode("div");2383 item = cont.pushNode("span", "<b>Transparency:</b> ");2384 var transp = cont.pushNode("input")2385 transp.type = "range"; transp.min = 0; transp.max = 255;2386 if (! settings.solid) transp.disabled = true;2387 transp.value = (settings.alphaSet === undefined ? 1 : settings.alphaSet)*255;2388 transp.oninput = function() {2389 settings.alphaSet = parseFloat(this.value)/255;2390 if (mesh.programs[0].settings.alphaSet != 1 && mesh.programs[0].pre_shader != UI.soup.renderer.shaders.alpha_dummy) mesh.programs[0].rebuild();2391 UI.soup.renderer.canvas.update = true;2392 };2393 cont.pushNode("br");2394 if ("sigma" in settings) {2395 cont = div.pushNode("div");2396 cont.pushNode("span", "Contour level ");2397 item = cont.pushNode("input");2398 item.value = settings.sigma;2399 item.type = "number";2400 item.min = 0; item.max = 10; item.step = 0.1;2401 item.onchange = function() {2402 settings.sigma = parseFloat(this.value);2403 UI.soup.load_ccp4(mesh, undefined, settings);2404 };2405 cont.pushNode("span", " \u03c3");2406 }2407 2408 if (options.ondelete) {2409 cont = div.pushNode("button", "Delete");2410 cont.onclick = function() {2411 if (options.ondelete) options.ondelete();2412 div.close();2413 };2414 }2415 2416 cont = div.pushNode("button", "Close");2417 cont.onclick = function() {2418 div.close();2419 };2420}2421molmil.UI.prototype.styleif_edmap = function(contentBox, callOptions) {2422 molmil.loadPlugin(molmil.settings.src+"plugins/misc.js");2423 molmil.loadPlugin(molmil.settings.src+"plugins/loaders.js");2424 2425 var UI = this;2426 2427 // check if edmap is supported && which files are available (both or 2fo-fc or fo-fc)2428 var struct = this.soup.structures[0];2429 if (! struct) return;2430 if (struct.meta.styleif === undefined) return setTimeout(function() {UI.styleif_edmap(contentBox, callOptions);}, 100);2431 var pdbid = struct.meta.pdbid.toLowerCase();2432 2433 var edmap2_downloads = function() {2434 molmil_dep.Clear(downloads);2435 var content = "<b>Downloads: </b>";2436 var idx;2437 var nwfls = struct.meta.styleif.__files;2438 2439 idx = nwfls.type.indexOf("sf");2440 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>Structure factors</a>';2441 2442 idx = nwfls.type.indexOf("2fo-fc-cif");2443 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>2fo-fc map (cif)</a>';2444 2445 idx = nwfls.type.indexOf("fo-fc-cif");2446 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>fo-fc map (cif)</a>';2447 2448 idx = nwfls.type.indexOf("2fo-fc-mtz");2449 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>2fo-fc map (mtz)</a>';2450 2451 idx = nwfls.type.indexOf("fo-fc-mtz");2452 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>fo-fc map (mtz)</a>';2453 2454 idx = nwfls.type.indexOf("2fo-fc-ccp4");2455 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>2fo-fc map (ccp4)</a>';2456 2457 idx = nwfls.type.indexOf("fo-fc-ccp4");2458 if (idx != -1) content += '<a href="'+molmil.settings.data_url+nwfls.name[idx]+'" download>fo-fc map (ccp4)</a>';2459 2460 downloads.innerHTML = content;2461 2462 for (var i=0; i<struct.meta.meshes.length; i++) {2463 var cont = downloads.pushNode("div");2464 var dl = cont.pushNode("span", "Download "+struct.meta.meshes[i].meta.filename);2465 dl.mesh = struct.meta.meshes[i];2466 dl.onclick = function() {2467 if (! window.saveAs) return molmil.loadPlugin(molmil.settings.src+"lib/FileSaver.js", this.onclick, this, []); 2468 var data = this.mesh.buffer;2469 saveAs(new Blob([data]), this.mesh.meta.filename);2470 };2471 2472 // drag_panel2473 2474 var options = cont.pushNode("p", "\u2699");2475 options.mesh = dl.mesh;2476 options.idx = i;2477 options.cont = cont;2478 options.onclick = function(ev) {2479 var idx = this.idx, cont = this.cont, mesh = this.mesh;2480 UI.styleif_mesh(this.mesh, ev, {ondelete: function() {2481 struct.meta.meshes.splice(idx, 1);2482 UI.soup.renderer.removeProgram(mesh.programs[0]);2483 UI.soup.structures.Remove(mesh);2484 UI.soup.renderer.canvas.update = true;2485 cont.parentNode.removeChild(cont);2486 }});2487 }2488 }2489 2490 }2491 2492 2493 contentBox.pushNode("h1", "EDMap options");2494 contentBox.pushNode("hr");2495 var has_2fofc = struct.meta.styleif.__files.type.includes("2fo-fc-mtz"), has_fofc = struct.meta.styleif.__files.type.includes("fo-fc-mtz");2496 if (! has_2fofc && ! has_fofc) {2497 contentBox.pushNode("span", "For this entry, no structure factor information is available.")2498 return;2499 }2500 2501 var mode = callOptions ? callOptions[0] : "both";2502 2503 var flexCont = contentBox.pushNode("div"); flexCont.style.display = "flex";2504 2505 var form = flexCont.pushNode("form");2506 form.pdbid = pdbid;2507 if (struct.meta.fileCounter === undefined) {2508 struct.meta.fileCounter = 0;2509 struct.meta.meshes = [];2510 }2511 form.mode = "wwpdb";2512 if (mode == "2fo-fc" || mode == "fo-fc") form.mode = mode;2513 2514 var cont, item, downloads = flexCont.pushNode("div"); downloads.id = "nw_edmap_dl";2515 cont = form.pushNode("span", "<b>Type of map:</b>");2516 2517 var handleMT = function() {2518 var A = this.value == "both" || this.value == "2fo-fc";2519 var B = this.value == "both" || this.value == "fo-fc";2520 form.sigma1.parentNode.style.display = A ? "" : "none";2521 form.sigma2.parentNode.style.display = B ? "" : "none";2522 }2523 2524 cont = form.pushNode("span");2525 item = cont.pushNode("label");2526 item.pushNode(molmil_dep.createINPUT("radio", "modeSel", "both"));2527 item.innerHTML += "Both"2528 item.firstChild.onchange = handleMT;2529 item = cont.pushNode("label");2530 item.pushNode(molmil_dep.createINPUT("radio", "modeSel", "2fo-fc"));2531 item.innerHTML += "2fo-fc";2532 item.firstChild.onchange = handleMT;2533 2534 item = cont.pushNode("label", );2535 item.pushNode(molmil_dep.createINPUT("radio", "modeSel", "fo-fc"));2536 item.innerHTML += "fo-fc";2537 item.firstChild.onchange = handleMT;2538 cont = form.pushNode("div");2539 item = cont.pushNode("span", "<b>Map size:</b> ");2540 item = cont.pushNode(molmil_dep.createTextBox("25")); item.name = "mapsize"; item.style.width = "4em";2541 item = cont.pushNode("span", " <b>\u212B</b>");2542 cont.pushNode("br");2543 2544 cont = form.pushNode("div");2545 item = cont.pushNode("span", "<b>Contour level (2fo-fc):</b> ");2546 item = cont.pushNode(molmil_dep.createTextBox("1")); item.name = "sigma1"; item.style.width = "4em";2547 item = cont.pushNode("span", " <b>\u03c3</b>");2548 cont = form.pushNode("div");2549 item = cont.pushNode("span", "<b>Contour level (fo-fc):</b> ");2550 item = cont.pushNode(molmil_dep.createTextBox("2")); item.name = "sigma2"; item.style.width = "4em";2551 item = cont.pushNode("span", " <b>\u03c3</b>");2552 cont.pushNode("br");2553 2554 2555 item = form.pushNode("button", "Create map");2556 item.onclick = function() {2557 var size = parseFloat(form.mapsize.value) || 25;2558 var sigma1 = parseFloat(form.sigma1.value) || 1;2559 var sigma2 = parseFloat(form.sigma2.value) || 2;2560 2561 if (! form.atom) {2562 alert("Please select an atom...");2563 return false;2564 }2565 var XYZ = [[form.atom.chain.modelsXYZ[0][form.atom.xyz], form.atom.chain.modelsXYZ[0][form.atom.xyz+1], form.atom.chain.modelsXYZ[0][form.atom.xyz+2]]];2566 var doRequest = function(mode, filename, red, green, blue, sigma) {2567 var request = new molmil_dep.CallRemote("POST");2568 request.AddParameter("xyz", JSON.stringify(XYZ));2569 request.AddParameter("border", form.mapsize.value*.5);2570 request.AddParameter("pdbid", pdbid);2571 request.AddParameter("mode", mode);2572 request.timeout = 0; request.ASYNC = true; request.responseType = "arraybuffer";2573 request.OnDone = function() {2574 var settings = {};2575 settings.sigma = parseFloat(sigma);2576 settings.solid = false;2577 settings.skipNormalization = true; // already normalized by mapmask2578 settings.skipCOG = true;2579 settings.denormalize = true;2580 settings.rgba = [red, green, blue, 255];2581 settings.alphaSet = 0.5;2582 var mesh = UI.soup.load_ccp4(this.request.response, filename, settings);2583 struct.meta.meshes.push(mesh);2584 edmap2_downloads();2585 };2586 request.Send(molmil.settings.newweb_rest+"edmap");2587 };2588 2589 if (form.modeSel[1].checked) doRequest("2fo-fc", "edmap_2fo-fc_"+struct.meta.fileCounter+".ccp4", 0, 255, 255, sigma1);2590 else if (form.modeSel[2].checked) doRequest("fo-fc", "edmap_fo-fc_"+struct.meta.fileCounter+".ccp4", 255, 0, 255, sigma2);2591 else if (form.modeSel[0].checked) {2592 doRequest("2fo-fc", "edmap_2fo-fc_"+struct.meta.fileCounter+".ccp4", 0, 255, 255, sigma1);2593 doRequest("fo-fc", "edmap_fo-fc_"+struct.meta.fileCounter+".ccp4", 255, 0, 255, sigma2);2594 }2595 else return false;2596 struct.meta.fileCounter++;2597 return false;2598 };2599 2600 if (callOptions) {2601 if (callOptions[0] == "2fo-fc") {2602 form.modeSel[1].checked = true;2603 form.modeSel[1].onchange();2604 }2605 else if (callOptions[0] == "fo-fc") {2606 form.modeSel[2].checked = true;2607 form.modeSel[2].onchange();2608 }2609 }2610 if (! form.modeSel[1].checked && ! form.modeSel[2].checked) {2611 form.modeSel[0].checked = true;2612 form.modeSel[0].onchange();2613 }2614 2615 2616 this.soup.onAtomPick = function(atom) {2617 form.atom = atom;2618 };2619 2620 edmap2_downloads();2621};2622molmil.UI.prototype.styleif_sites = function(contentBox) {2623 var UI = this;2624 2625 var mmjsonGroupData = function(obj, field) {2626 if (! obj) return {};2627 var output = {}, tmp;2628 var keys = Object.keys(obj);2629 for (var i=0, k; i<obj[field].length; i++) {2630 if (! (obj[field][i] in output)) output[obj[field][i]] = [];2631 tmp = {};2632 for (k=0; k<keys.length; k++) tmp[keys[k]] = obj[keys[k]][i];2633 output[obj[field][i]].push(tmp);2634 }2635 return output;2636 }2637 2638 var toggleSite = function() {2639 if (this.checked) {2640 molmil.displayEntry(this.data.residueList, molmil.displayMode_Stick_SC, false, UI.soup);2641 molmil.colorEntry(this.data.residueList, molmil.colorEntry_Custom+.5, {rgba: this.data.color, carbonOnly: true}, false, UI.soup);2642 }2643 else {2644 molmil.displayEntry(this.data.residueList, molmil.displayMode_Default, false, UI.soup);2645 molmil.colorEntry(this.data.residueList, molmil.colorEntry_CPK, null, false, UI.soup);2646 }2647 2648 UI.soup.renderer.initBuffers();2649 UI.soup.renderer.canvas.update = true; 2650 };2651 2652 2653 for (var s=0; s<this.soup.structures.length; s++) {2654 var struct = this.soup.structures[s];2655 if (! struct && ! struct.meta || ! struct.meta.pdbid) continue;2656 if (struct.meta.styleif === undefined) return setTimeout(function() {UI.styleif_sites(contentBox);}, 100);2657 }2658 2659 var downloads = contentBox.pushNode("div"); downloads.id = "nw_edmap_dl";2660 2661 for (var i=0; i<this.soup.structures.length; i++) {2662 if (! this.soup.structures[i].meta || ! this.soup.structures[i].meta.filename || ! this.soup.structures[i].meta.filename.endsWith(".mpbf")) continue;2663 var cont = downloads.pushNode("div");2664 cont.pushNode("span", this.soup.structures[i].meta.filename);2665 2666 // afterwards split this up over multiple sub-meshes... (for large structures);2667 2668 var options = cont.pushNode("p", "\u2699");2669 options.filename = this.soup.structures[i].meta.filename;2670 options.mesh = this.soup.structures[i].structures[0];2671 options.onclick = function(ev) {2672 UI.styleif_mesh(this.mesh, ev, {filename: this.filename});2673 }2674 UI.showSites = true;2675 }2676 2677 for (var s=0; s<this.soup.structures.length; s++) {2678 var struct = this.soup.structures[s];2679 if (! struct && ! struct.meta || ! struct.meta.pdbid) continue;2680 2681 var pdbid = struct.meta.pdbid.toLowerCase();2682 if (! struct.meta.styleif.fgroups) {2683 var struct_site_pdbmlplus = struct.meta.styleif.struct_site_pdbmlplus || {info_subtype: []},2684 struct_site_gen_pdbmlplus = struct.meta.styleif.struct_site_gen_pdbmlplus,2685 entity_poly = struct.meta.pdbxData.entity_poly || struct.meta.styleif.entity_poly,2686 struct_site = struct.meta.pdbxData.struct_site || struct.meta.styleif.struct_site || {id: []},2687 struct_site_gen = struct.meta.pdbxData.struct_site_gen || struct.meta.styleif.struct_site_gen;2688 2689 var buffer = {};2690 for (var e in struct_site_pdbmlplus) buffer[e] = struct_site_pdbmlplus[e].map(function(x) {return x;});2691 for (var e in struct_site) {2692 if (! (e in buffer)) buffer[e] = [];2693 buffer[e].push.apply(buffer[e], struct_site[e]);2694 }2695 2696 var buffer2 = mmjsonGroupData(struct_site_gen_pdbmlplus, "site_id");2697 var tmp = mmjsonGroupData(struct_site_gen, "site_id");2698 for (var e in tmp) buffer2[e] = tmp[e];2699 2700 var fgroups = [], fgroup;2701 2702 var chainid, resid, residx, residx2, chains, c, r, tmp, tmp2, tmpList, seq, i, j, mol;2703 2704 2705 var aaCode = {"ALA":"A","CYS":"C","ASP":"D","GLU":"E","PHE":"F","GLY":"G","HIS":"H","ILE":"I","LYS":"K","LEU":"L","MET":"M","ASN":"N","PYL":"O","PRO":"P","GLN":"Q","ARG":"R","SER":"S","THR":"T","SEC":"U","VAL":"V","TRP":"W","TYR":"Y"} ;2706 for (i=0; i<buffer.id.length; i++) {2707 fgroup = {2708 name: "", 2709 sequence: [],2710 description: buffer.details[i],2711 source: buffer.info_subtype[i] ? buffer.info_subtype[i]+" : "+buffer.id[i] : undefined,2712 residueList: [] // list of molObject/s 2713 };2714 2715 residues = buffer2[buffer.id[i]] || [];2716 tmp = [];2717 fgroup.ligand = residues.length ? residues[0].ligand : null;2718 if (buffer.info_subtype[i] == "binding" || buffer.info_subtype[i] == "prosite") {2719 for (r=0; r<residues.length; r++) {2720 tmpList = [];2721 2722 chainid = residues[r].auth_asym_id;2723 residx = parseInt(residues[r].beg_auth_seq_id);2724 residx2 = parseInt(residues[r].end_auth_seq_id);2725 chains = UI.soup.getChainAuth(struct, chainid);2726 2727 for (c=residx; c<=residx2; c++) {2728 mol = UI.soup.getMolObject4ChainAlt(chains, c);2729 if (! mol) continue;2730 fgroup.sequence.push(aaCode[mol.name] || mol.name);2731 fgroup.residueList.push(mol);2732 }2733 tmp.push([chainid+": "+residues[r].beg_auth_seq_id+(residues[r].beg_auth_seq_id != residues[r].end_auth_seq_id ? "-"+residues[r].end_auth_seq_id : "")]);2734 }2735 }2736 else {2737 for (r=0; r<residues.length; r++) {2738 tmpList = [];2739 chainid = residues[r].auth_asym_id; residx = null; tmp2 = [], residx = residx2 = null;2740 if (residues[r].beg_auth_seq_id) {2741 try {2742 residx = parseInt(residues[r].beg_auth_seq_id.replace(/\D/g,''));2743 residx2 = parseInt(residues[r].end_auth_seq_id.replace(/\D/g,''));2744 tmp2 = [residues[r].beg_auth_seq_id, residues[r].end_auth_seq_id];2745 }2746 catch (e) {}2747 }2748 if (residx == null) {2749 if (! residues[r].auth_seq_id) continue;2750 resid2 = residx = parseInt(residues[r].auth_seq_id.replace(/\D/g,''));2751 tmp2 = [null, null];2752 }2753 if (! residx2) residx2 = residx;2754 chains = UI.soup.getChainAuth(struct, chainid);2755 for (c=residx; c<=residx2; c++) {2756 mol = UI.soup.getMolObject4ChainAlt(chains, c);2757 if (! mol) continue;2758 fgroup.sequence.push(aaCode[mol.name] || mol.name);2759 fgroup.residueList.push(mol);2760 }2761 try {2762 if (tmp2[0] == null) tmp2 = [UI.soup.getMolObject4ChainAlt(chains, residx).RSID, UI.soup.getMolObject4ChainAlt(chains, residx2).RSID];2763 }2764 catch (e) {}2765 if (tmp2[0] != null) tmp.push([chainid+": "+tmp2[0]+(tmp2[0] != tmp2[1] ? "-"+tmp2[1] : "")]);2766 }2767 }2768 2769 fgroup.name = tmp.join(", ")+(buffer.info_subtype[i] && buffer.info_subtype[i] != "pdb" ? " ("+buffer.info_subtype[i]+")" : "");2770 if (fgroup.residueList.length) fgroups.push(fgroup);2771 }2772 }2773 else var fgroups = struct.meta.styleif.fgroups;2774 2775 var tbl = molmil_dep.dcE("table"), tr, td, tbl2, tr2, td2, check;2776 tbl.id = "nw_site_tbl";2777 2778 var site_color_list = molmil.configBox.bu_colors;2779 var n = 0;2780 var arr = [];2781 var top = null;2782 for (var i=0; i<fgroups.length; i++) {2783 var nrows = tbl.rows.length;2784 2785 tr = tbl.pushNode("tr");2786 2787 top = td = tr.pushNode("td");2788 check = td.pushNode("input");2789 check.type = "checkbox";2790 check.onchange = toggleSite;2791 check.data = fgroups[i];2792 check.data.color = [site_color_list[n][0], site_color_list[n][1], site_color_list[n][2], 255];2793 2794 td = tr.pushNode("td", fgroups[i].name)2795 td.colSpan = 2;2796 td.style.color = "rgba("+site_color_list[n].join(",")+")";2797 td.onclick = function() {this.check.click();};2798 td.ondblclick = function() {2799 this.check.checked = false;2800 this.check.click();2801 var atoms = this.check.data.residueList.map(function(x) {return x.atoms;}).flat();2802 molmil.orient(atoms, UI.soup);2803 }2804 td.check = check;2805 if (fgroups[i].sequence) {2806 tr = tbl.pushNode("tr");2807 tr.pushNode("td", "Sequence:");2808 tr.pushNode("td", fgroups[i].sequence.join(", "));2809 }2810 2811 if (fgroups[i].description) {2812 tr = tbl.pushNode("tr");2813 tr.pushNode("td", "Description:");2814 tr.pushNode("td", fgroups[i].description);2815 }2816 2817 if (fgroups[i].source) {2818 tr = tbl.pushNode("tr");2819 tr.pushNode("td", "Source:");2820 tr.pushNode("td", fgroups[i].source);2821 }2822 2823 if (fgroups[i].ligand) {2824 tr = tbl.pushNode("tr");2825 tr.pushNode("td", "Ligand:");2826 tr.pushNode("td", fgroups[i].ligand);2827 }2828 2829 top.rowSpan = (tbl.rows.length-nrows);2830 2831 n += 1;2832 if (n >= site_color_list.length) n = 0;2833 }2834 contentBox.pushNode("span", struct.meta.id)2835 contentBox.pushNode(tbl);2836 2837 }2838};2839molmil.UI.prototype.styleif_align = function(contentBox) {2840 var UI = this;2841 2842 const alignments = [];2843 2844 contentBox.id = "nw_align";2845 2846 for (var i in molmil.alignInfo) {2847 if (! UI.soup.chains.includes(molmil.alignInfo[i].chain1) || ! UI.soup.chains.includes(molmil.alignInfo[i].chain2)) continue;2848 alignments.push(molmil.alignInfo[i]);2849 }2850 2851 if (alignments.length > 1) {2852 for (var i=0; i<alignments.length; i++) {2853 var tmp = contentBox.pushNode("span", alignments[i].chain1.CID + " vs " + alignments[i].chain2.CID);2854 tmp.aid = i;2855 tmp.onclick = function() {show(this.aid);};2856 }2857 }2858 2859 2860 var alignmentInfo = contentBox.pushNode("div"), nlen = 60;2861 var show = function(aid) {2862 molmil_dep.Clear(alignmentInfo);2863 2864 var alignment = alignments[aid];2865 if (! alignment) return;2866 var name1 = alignment.chain1.entry.meta.id.indexOf("_") == -1 ? alignment.chain1.entry.meta.pdbid + alignment.chain1.name : alignment.chain1.entry.meta.id;2867 var name2 = alignment.chain2.entry.meta.id.indexOf("_") == -1 ? alignment.chain2.entry.meta.pdbid + alignment.chain2.name : alignment.chain2.entry.meta.id;2868 alignmentInfo.pushNode("div", "Alignment of <b style='color: cyan;'>"+name1+"</b> vs <b style='color: magenta;'>"+name2+"</b>");2869 alignmentInfo.pushNode("div", "Initial RMSD: " + alignment.initial_rmsd.toFixed(2) + " \u212B (over all matched residues)");2870 alignmentInfo.pushNode("div", "Optimized RMSD: " + alignment.rmsd.toFixed(2) + " \u212B (over all green matched residues)");2871 var alignTable = alignmentInfo.pushNode("table"), tr;2872 var pos = 0, c1pos = 0, c2pos = 0;2873 while (true) {2874 fpos = pos + nlen;2875 if (fpos >= alignment.alignment.length) fpos = alignment.alignment.length-1;2876 2877 tr = alignTable.pushNode("tr");2878 tr.pushNode("td", alignment.chain1.molecules[c1pos].RSID);2879 tr.pushNode("td", alignment.seq1.substring(pos, fpos));2880 c1pos += Array.from(alignment.seq1.substring(pos, fpos)).filter(x=>x!="-").length;2881 tr.pushNode("td", c1pos ? alignment.chain1.molecules[c1pos-1].RSID : alignment.chain1.molecules[c1pos].RSID);2882 2883 var tmp = alignment.optimized_alignment.substring(pos, fpos);2884 var tmp2 = Array.from(alignment.alignment.substring(pos, fpos)).map(function(x, i) {return tmp[i] == "|" ? "<b>|</b>" : x;}).join("");2885 tr = alignTable.pushNode("tr");2886 tr.pushNode("td", "");2887 tr.pushNode("td", tmp2).classList.add("nw_align_align");2888 tr.pushNode("td", "");2889 tr = alignTable.pushNode("tr");2890 tr.pushNode("td", alignment.chain2.molecules[c2pos].RSID);2891 tr.pushNode("td", alignment.seq2.substring(pos, fpos));2892 c2pos += Array.from(alignment.seq2.substring(pos, fpos)).filter(x=>x!="-").length;2893 tr.pushNode("td", alignment.chain2.molecules[c2pos-1].RSID);2894 2895 pos += nlen;2896 if (pos >= alignment.alignment.length) break;2897 }2898 };2899 show(0);2900};2901molmil.UI.prototype.styleif_settings = function(contentBox) {2902/*2903 if (this.LM && this.LM.parentNode.childNodes.length > 1) this.LM.onclick();2904 if (this.onLMshow) this.onLMshow();2905 2906 var canvas = this.soup.canvas;2907 2908 var popup = molmil_dep.dcE("div");2909 popup.setClass("molmil_menu_popup");2910 2911 popup.pushNode("div", "Slab configuration");2912 popup.pushNode("hr");2913 2914 2915 var table = popup.pushNode("table"), tr, td;2916 var slab_near, slab_far2917 tr = table.pushNode("tr");2918 tr.pushNode("td", "Slab near:");2919 slab_near = tr.pushNode("td").pushNode("input");2920 slab_near.type = "range";2921 td = tr.pushNode("td", "0"); td.style.minWidth = "4em"; td.style.textAlign = "right";2922 2923 tr = table.pushNode("tr");2924 tr.pushNode("td", "Slab far:");2925 slab_far = tr.pushNode("td").pushNode("input");2926 slab_far.type = "range";2927 td = tr.pushNode("td", "0"); td.style.minWidth = "4em"; td.style.textAlign = "right";2928 2929 slab_near.oninput = function() { // handle modification of the slab-near slider2930 this.parentNode.nextSibling.innerHTML = Math.round(parseFloat(this.value)*10)/10;2931 if (parseFloat(slab_far.value) <= parseFloat(this.value)) {2932 slab_far.value = parseFloat(this.value)+1;2933 slab_far.oninput();2934 }2935 else molmil.setSlab(parseFloat(slab_near.value), parseFloat(slab_far.value), canvas.molmilViewer); // sets the slab values2936 };2937 2938 slab_far.oninput = function() { // handle modification of the slab-far slider2939 this.parentNode.nextSibling.innerHTML = Math.round(parseFloat(this.value)*10)/10;2940 if (parseFloat(slab_near.value) >= parseFloat(this.value)) {2941 slab_near.value = parseFloat(this.value)-1;2942 slab_near.oninput();2943 }2944 else molmil.setSlab(parseFloat(slab_near.value), parseFloat(slab_far.value), canvas.molmilViewer); // sets the slab values2945 };2946 var szI = Math.min(this.soup.geomRanges[0], this.soup.geomRanges[2], this.soup.geomRanges[4]) + molmil.configBox.zNear;2947 var szA = Math.max(this.soup.geomRanges[1], this.soup.geomRanges[3], this.soup.geomRanges[5]) + molmil.configBox.zNear;2948 if (szI > szA - 1) szA = szI + 1;2949 2950 slab_near.min = slab_far.min = szI;2951 slab_near.max = slab_far.max = szA;2952 2953 slab_near.step = slab_far.step = .1;2954 2955 slab_near.value = this.soup.renderer.settings.slabNear || szI;2956 slab_far.value = this.soup.renderer.settings.slabFar || szA2957 slab_near.oninput();2958 slab_far.oninput();2959 2960 2961 var closeButton = popup.pushNode("button", "Close");2962 closeButton.style.marginLeft = "1em";2963 var UI = this;2964 closeButton.onclick = function() {popup.parentNode.removeChild(popup); if (UI.onLMhide) UI.onLMhide();};2965 2966 if (target) target.pushNode(popup);2967 else this.LM.parentNode.pushNode(popup);2968*/2969 2970 var UI = this;2971 var saveContainer = {}, tmp;2972 2973 var easySet = function(what, to) {2974 if (localStorage.getItem(what) == to) return;2975 localStorage.setItem(what, to);2976 return true;2977 };2978 2979 var applyUpdate = function() {2980 var resizeVP = false, recompile = false, rebuild = false, slab = false;2981 2982 // save settings2983 if (easySet("molmil.settings_QLV", saveContainer.qlv.value)) {2984 rebuild = true;2985 }2986 if (easySet("molmil.settings_glsl_fog", (molmil.configBox.glsl_fog=saveContainer.fog.checked) ? "1" : "0")) {2987 recompile = true;2988 if (saveContainer.fog.checked) saveContainer.slab.toggle.checked = UI.soup.renderer.settings.slab = false;2989 }2990 if (easySet("molmil.settings_PROJECTION", saveContainer.projectionMode.value)) {2991 resizeVP = true;2992 }2993 if (easySet("molmil.settings_STEREO", saveContainer.stereoMode.value)) {2994 2995 }2996 if (easySet("molmil.settings_BGCOLOR", JSON.stringify(molmil.hex2rgb(saveContainer.bgcolor.RGB.value).concat([parseInt(saveContainer.bgcolor.A.value)]).map(function(x){return x/255;})))) {2997 2998 }2999 if (easySet("molmil.settings_keepBackgroundColor", saveContainer.bgcolor.keepbgpng.checked ? "1" : "0")) {3000 3001 }3002 if (easySet("molmil.settings_BBSF", saveContainer.bbsf.value)) {3003 rebuild = true;3004 molmil.geometry.reInitChains = true;3005 }3006 3007 if (easySet("molmil.settings_slab_near_ratio", saveContainer.slab.near.value)) slab = true;3008 if (easySet("molmil.settings_slab_far_ratio", saveContainer.slab.far.value)) slab = true;3009 3010 // reload settings3011 molmil.initSettings();3012 UI.soup.reloadSettings();3013 molmil.configBox.projectionMode = saveContainer.projectionMode.value; molmil.configBox.stereoMode = parseInt(saveContainer.stereoMode.value); 3014 3015 if (saveContainer.slab.toggle.checked != UI.soup.renderer.settings.slab) {3016 UI.soup.renderer.settings.slab = saveContainer.slab.toggle.checked;3017 slab = true;3018 recompile = true;3019 }3020 3021 if (resizeVP) UI.soup.renderer.resizeViewPort();3022 if (recompile) molmil.shaderEngine.recompile(UI.soup.renderer);3023 if (slab) {3024 var szI = Math.min(UI.soup.geomRanges[0], UI.soup.geomRanges[2], UI.soup.geomRanges[4]) + molmil.configBox.zNear;3025 var szA = Math.max(UI.soup.geomRanges[1], UI.soup.geomRanges[3], UI.soup.geomRanges[5]) + molmil.configBox.zNear;3026 if (szI > szA - 1) szA = szI + 1;3027 3028 var tot = szA-szI;3029 UI.soup.renderer.settings.slabNear = parseFloat(saveContainer.slab.near.value)*tot + szI;3030 UI.soup.renderer.settings.slabFar = parseFloat(saveContainer.slab.far.value)*tot + szI;3031 }3032 3033 // re-render3034 if (rebuild) UI.soup.renderer.initBuffers();3035 UI.soup.canvas.update = true;3036 };3037 3038 3039 contentBox.id = "nw_settings";3040 contentBox.pushNode("h1", "Settings");3041 contentBox.pushNode("hr");3042 3043 3044 saveContainer.qlv = molmil_dep.dcE("input");3045 saveContainer.qlv.type = "range"; saveContainer.qlv.min = "0"; saveContainer.qlv.max = "4"; saveContainer.qlv.step = "1";3046 saveContainer.qlv.value = localStorage.getItem("molmil.settings_QLV");3047 saveContainer.qlv.ref = molmil_dep.dcE("span"); saveContainer.qlv.ref.innerHTML = saveContainer.qlv.value;3048 saveContainer.qlv.onmousemove = function() {this.ref.innerHTML = this.value;};3049 saveContainer.qlv.onchange = function() {applyUpdate();}3050 3051 saveContainer.bbsf = molmil_dep.dcE("input");3052 saveContainer.bbsf.type = "range"; saveContainer.bbsf.min = "0"; saveContainer.bbsf.max = "4"; saveContainer.bbsf.step = "1";3053 saveContainer.bbsf.value = molmil.configBox.smoothFactor;3054 saveContainer.bbsf.ref = molmil_dep.dcE("span"); saveContainer.bbsf.ref.innerHTML = saveContainer.bbsf.value;3055 saveContainer.bbsf.onmousemove = function() {this.ref.innerHTML = this.value;};3056 saveContainer.bbsf.onchange = function() {applyUpdate();}3057 3058 3059 // split into basic and slab modes...3060 3061 saveContainer.fog = molmil_dep.dcE("input");3062 saveContainer.fog.type = "checkbox";3063 saveContainer.fog.checked = localStorage.getItem("molmil.settings_glsl_fog") == 1;3064 saveContainer.fog.onchange = function() {3065 saveContainer.slab.toggle.disabled = saveContainer.slab.near.disabled = saveContainer.slab.far.disabled = saveContainer.fog.checked;3066 applyUpdate();3067 }3068 3069 saveContainer.slab = molmil_dep.dcE("span");3070 saveContainer.slab.toggle = saveContainer.slab.pushNode("input");3071 saveContainer.slab.pushNode("span", " | Near: ");3072 3073 saveContainer.slab.near = saveContainer.slab.pushNode("input");3074 saveContainer.slab.pushNode("span", " | Far: ");3075 saveContainer.slab.far = saveContainer.slab.pushNode("input");3076 3077 saveContainer.slab.toggle.type = "checkbox";3078 saveContainer.slab.near.type = saveContainer.slab.far.type = "range";3079 3080 saveContainer.slab.near.min = saveContainer.slab.far.min = 0;3081 saveContainer.slab.near.max = saveContainer.slab.far.max = 1;3082 saveContainer.slab.near.step = saveContainer.slab.far.step = 0.001;3083 saveContainer.slab.toggle.disabled = saveContainer.slab.near.disabled = saveContainer.slab.far.disabled = saveContainer.fog.checked;3084 3085 saveContainer.slab.toggle.checked = UI.soup.renderer.settings.slab;3086 saveContainer.slab.near.value = molmil.configBox.slab_near_ratio;3087 saveContainer.slab.far.value = molmil.configBox.slab_far_ratio;3088 saveContainer.slab.near.oninput = saveContainer.slab.far.oninput = function() {applyUpdate();}3089 saveContainer.slab.toggle.onchange = function() {applyUpdate();}3090 3091 3092 saveContainer.projectionMode = molmil_dep.dcE("select");3093 tmp = saveContainer.projectionMode.pushNode("option", "Perspective projection"); tmp.value = 1;3094 tmp = saveContainer.projectionMode.pushNode("option", "Orthographic projection"); tmp.value = 2;3095 if (molmil.configBox.projectionMode == 2) tmp.selected = true;3096 saveContainer.projectionMode.onchange = function() {applyUpdate();}3097 3098 saveContainer.stereoMode = molmil_dep.dcE("select");3099 tmp = saveContainer.stereoMode.pushNode("option", "None"); tmp.value = 0;3100 tmp = saveContainer.stereoMode.pushNode("option", "Anaglyph"); tmp.value = 1;3101 if (molmil.configBox.stereoMode == 1) tmp.selected = true;3102 tmp = saveContainer.stereoMode.pushNode("option", "Side-by-side"); tmp.value = 2;3103 if (molmil.configBox.stereoMode == 2) tmp.selected = true;3104 tmp = saveContainer.stereoMode.pushNode("option", "Cross-eyed"); tmp.value = 4;3105 if (molmil.configBox.stereoMode == 4) tmp.selected = true;3106 saveContainer.stereoMode.onchange = function() {applyUpdate();}3107 3108 //change this to a proper color input + slider for alpha3109 saveContainer.bgcolor = molmil_dep.dcE("span");3110 3111 saveContainer.bgcolor.RGB = saveContainer.bgcolor.pushNode("input");3112 saveContainer.bgcolor.RGB.value = molmil.rgb2hex(molmil.configBox.BGCOLOR[0]*255, molmil.configBox.BGCOLOR[1]*255, molmil.configBox.BGCOLOR[2]*255);3113 saveContainer.bgcolor.RGB.type = "color";3114 saveContainer.bgcolor.RGB.onchange = function() {applyUpdate();}3115 3116 saveContainer.bgcolor.pushNode("span", " Transparency:");3117 saveContainer.bgcolor.A = saveContainer.bgcolor.pushNode("input");3118 saveContainer.bgcolor.A.type = "range";3119 saveContainer.bgcolor.A.min = 0; saveContainer.bgcolor.A.max = 255; saveContainer.bgcolor.A.step = 1; saveContainer.bgcolor.A.value = molmil.configBox.BGCOLOR[3]*255;3120 saveContainer.bgcolor.A.ref = saveContainer.bgcolor.pushNode("span"); saveContainer.bgcolor.A.ref.innerHTML = saveContainer.bgcolor.A.value;3121 saveContainer.bgcolor.A.onmousemove = function() {this.ref.innerHTML = this.value;};3122 saveContainer.bgcolor.A.onchange = function() {applyUpdate();}3123 3124 saveContainer.bgcolor.pushNode("span", "<br/>Apply BG color in png:");3125 saveContainer.bgcolor.keepbgpng = saveContainer.bgcolor.pushNode("input");3126 saveContainer.bgcolor.keepbgpng.type = "checkbox";3127 saveContainer.bgcolor.keepbgpng.checked = molmil.configBox.keepBackgroundColor;3128 saveContainer.bgcolor.keepbgpng.onchange = function() {applyUpdate();}3129 var tbl = contentBox.pushNode("table"), tr, tmp;3130 tr = tbl.pushNode("tr");3131 tr.pushNode("td", "Quality:");3132 tmp = molmil_dep.dcE("div");3133 tmp.pushNode(saveContainer.qlv);3134 tmp.pushNode(saveContainer.qlv.ref);3135 tr.pushNode("td").pushNode(tmp);3136 3137 3138 tr = tbl.pushNode("tr");3139 tr.pushNode("td", "Sheet/loop backbone smooth factor:");3140 tmp = molmil_dep.dcE("div");3141 tmp.pushNode(saveContainer.bbsf);3142 tmp.pushNode(saveContainer.bbsf.ref);3143 tr.pushNode("td").pushNode(tmp);3144 3145 tr = tbl.pushNode("tr");3146 tr.pushNode("td", "Fog:");3147 tmp = molmil_dep.dcE("div");3148 tmp.pushNode(saveContainer.fog);3149 tr.pushNode("td").pushNode(tmp);3150 3151 tr = tbl.pushNode("tr");3152 tr.pushNode("td", "Slab:");3153 tmp = molmil_dep.dcE("div");3154 tmp.pushNode(saveContainer.slab);3155 tr.pushNode("td").pushNode(tmp);3156 3157 tr = tbl.pushNode("tr");3158 tr.pushNode("td", "Projection mode:");3159 tr.pushNode("td").pushNode(saveContainer.projectionMode);3160 3161 tr = tbl.pushNode("tr");3162 tr.pushNode("td", "Stereoscopy:");3163 tr.pushNode("td").pushNode(saveContainer.stereoMode);3164 3165 tr = tbl.pushNode("tr");3166 tr.pushNode("td", "BG color:");3167 tr.pushNode("td").pushNode(saveContainer.bgcolor);3168};3169molmil.UI.prototype.styleif = function(showOption, callOptions) {3170 var UI = this;3171 var initStruct = function(struct) {3172 if (! struct.meta.id || ! struct.meta.pdbid) return;3173 var pdbid = struct.meta.pdbid.toLowerCase();3174 if (struct.meta.styleif === undefined) {3175 var request = new molmil_dep.CallRemote("GET"); request.ASYNC = true; 3176 request.OnDone = function() {3177 var jso = JSON.parse(this.request.responseText);3178 struct.meta.styleif = Object.values(jso)[0];3179 var has_2fofc = struct.meta.styleif.__files.type.includes("2fo-fc-mtz"), has_fofc = struct.meta.styleif.__files.type.includes("fo-fc-mtz");3180 if (has_2fofc) UI.showEDMap = true;3181 var tmp1 = struct.meta.styleif.struct_site_pdbmlplus || {info_subtype: []};3182 var tmp2 = struct.meta.pdbxData.struct_site || struct.meta.styleif.struct_site || {id: []};3183 if (tmp1.info_subtype.length || tmp2.id.length) UI.showSites = true;3184 };3185 request.Send(molmil.settings.newweb_rest+"fetch/rdb?entryId="+pdbid+"&schemaName=pdbj&tables=__files,struct_site_pdbmlplus,struct_site_gen_pdbmlplus"+("entity_poly" in struct.meta.pdbxData ? "" : ",entity_poly,struct_site,struct_site_gen"));3186 }3187 };3188 3189 for (var i=0; i<UI.soup.structures.length; i++) initStruct(UI.soup.structures[i]);3190 3191 var nwif = document.getElementById("styleif");3192 if (! nwif) {3193 nwif = this.canvas.parentNode.pushNode("div");3194 nwif.id = "styleif";3195 nwif.contentBox = nwif.pushNode("div");3196 if (window.MutationObserver !== undefined) {3197 var styleif_height = localStorage.getItem("molmil.settings_styleif_height");3198 if (styleif_height != "hidden") nwif.contentBox.style.height = styleif_height;3199 else showOption = "hide";3200 var observer = new MutationObserver(function(mutations) {3201 if (nwif.contentBox.classList.contains("visible")) localStorage.setItem("molmil.settings_styleif_height", nwif.contentBox.style.height);3202 else localStorage.setItem("molmil.settings_styleif_height", "hidden");3203 });3204 observer.observe(nwif.contentBox, { attributes: true });3205 }3206 nwif.button = nwif.pushNode("div", "Style menu"); // see if we can also make this button dragable, so that it can be used to resize the menu...3207 nwif.options = nwif.pushNode("div");3208 3209 // see if we can also hide the sites option, if none are available...3210 var options = [["Structure", "structure"], ["BU", "bu", function() {return ! UI.soup.AisB;}], ["EDMap", "edmap", function() {return UI.showEDMap;}], ["Sites", "sites", function() {return UI.showSites;}], ["Alignment", "align", function() {return Object.keys(molmil.alignInfo).length;}], ["Settings", "settings"], ["Hide", "hide"]];3211 3212 var doHandler = function(ev, callOptions) {3213 if (this.value == "structure") {3214 molmil_dep.Clear(nwif.contentBox);3215 UI.styleif_au(nwif.contentBox);3216 nwif.contentBox.classList.add("visible");3217 }3218 else if (this.value == "bu") {3219 molmil_dep.Clear(nwif.contentBox);3220 UI.styleif_bu(nwif.contentBox);3221 nwif.contentBox.classList.add("visible");3222 }3223 else if (this.value == "edmap") {3224 molmil_dep.Clear(nwif.contentBox);3225 UI.styleif_edmap(nwif.contentBox, callOptions);3226 nwif.contentBox.classList.add("visible");3227 }3228 else if (this.value == "sites") {3229 molmil_dep.Clear(nwif.contentBox);3230 UI.styleif_sites(nwif.contentBox);3231 nwif.contentBox.classList.add("visible");3232 }3233 else if (this.value == "align") {3234 molmil_dep.Clear(nwif.contentBox);3235 UI.styleif_align(nwif.contentBox);3236 nwif.contentBox.classList.add("visible");3237 }3238 else if (this.value == "settings") {3239 molmil_dep.Clear(nwif.contentBox);3240 UI.styleif_settings(nwif.contentBox);3241 nwif.contentBox.classList.add("visible");3242 }3243 else if (this.value == "hide") {3244 nwif.contentBox.classList.remove("visible");3245 }3246 if (! nwif.contentBox.classList.contains("visible")) {3247 if (nwif.firstChild.style.height) nwif.heightSet = nwif.firstChild.style.height;3248 nwif.firstChild.style.height = "";3249 }3250 else if (nwif.heightSet) nwif.firstChild.style.height = nwif.heightSet;3251 3252 nwif.options.classList.remove("visible");3253 };3254 3255 for (var i=0; i<options.length; i++) {3256 var opt = nwif.options.pushNode("div", options[i][0]);3257 if (options[i][2]) opt.checkHandler = options[i][2];3258 else opt.checkHandler = function() {return true;};3259 opt.value = options[i][1];3260 opt.onclick = doHandler;3261 }3262 3263 nwif.button.onclick = function() {3264 for (var i=0; i<nwif.options.childNodes.length; i++) nwif.options.childNodes[i].style.display = nwif.options.childNodes[i].checkHandler() ? "" : "none";3265 nwif.options.classList.toggle("visible");3266 }3267 }3268 3269 if (showOption == "bu" && UI.soup.AisB) showOption = "structure";3270 ...
test.js
Source:test.js
...171 });172 describe('.pushNode', function() {173 it('should throw an error when not a node', function() {174 assert.throws(function() {175 utils.pushNode();176 });177 });178 it('should add a node to the end of node.nodes', function() {179 var node = new Node({type: 'brace'});180 var a = new Node({type: 'a', value: 'foo'});181 var b = new Node({type: 'b', value: 'foo'});182 utils.pushNode(node, a);183 utils.pushNode(node, b);184 assert.equal(node.nodes[0].type, 'a');185 assert.equal(node.nodes[1].type, 'b');186 });187 it('should work when node.push is not a function', function() {188 var node = new Node({type: 'brace'});189 var a = new Node({type: 'a', value: 'foo'});190 var b = new Node({type: 'b', value: 'foo'});191 node.pushNode = null;192 node.push = null;193 utils.pushNode(node, a);194 utils.pushNode(node, b);195 assert.equal(node.nodes[0].type, 'a');196 assert.equal(node.nodes[1].type, 'b');197 });198 });199 describe('.unshiftNode', function() {200 it('should throw an error when parent is not a node', function() {201 assert.throws(function() {202 utils.unshiftNode();203 });204 });205 it('should add a node to the beginning of node.nodes', function() {206 var node = new Node({type: 'brace'});207 var a = new Node({type: 'a', value: 'foo'});208 var b = new Node({type: 'b', value: 'foo'});209 utils.unshiftNode(node, a);210 utils.unshiftNode(node, b);211 assert.equal(node.nodes[1].type, 'a');212 assert.equal(node.nodes[0].type, 'b');213 });214 it('should work when node.unshift is not a function', function() {215 var node = new Node({type: 'brace'});216 var a = new Node({type: 'a', value: 'foo'});217 var b = new Node({type: 'b', value: 'foo'});218 node.unshiftNode = null;219 node.unshift = null;220 utils.unshiftNode(node, a);221 utils.unshiftNode(node, b);222 assert.equal(node.nodes[1].type, 'a');223 assert.equal(node.nodes[0].type, 'b');224 });225 });226 describe('.popNode', function() {227 it('should throw an error when not a node', function() {228 assert.throws(function() {229 utils.popNode();230 });231 });232 it('should pop a node from node.nodes', function() {233 var node = new Node({type: 'brace'});234 var a = new Node({type: 'a', value: 'foo'});235 var b = new Node({type: 'b', value: 'foo'});236 utils.pushNode(node, a);237 utils.pushNode(node, b);238 assert.equal(node.nodes[0].type, 'a');239 assert.equal(node.nodes[1].type, 'b');240 utils.popNode(node);241 utils.popNode(node);242 assert.equal(node.nodes.length, 0);243 });244 it('should work when node.pop is not a function', function() {245 var node = new Node({type: 'brace'});246 var a = new Node({type: 'a', value: 'foo'});247 var b = new Node({type: 'b', value: 'foo'});248 node.popNode = null;249 node.pop = null;250 utils.pushNode(node, a);251 utils.pushNode(node, b);252 assert.equal(node.nodes[0].type, 'a');253 assert.equal(node.nodes[1].type, 'b');254 utils.popNode(node);255 utils.popNode(node);256 assert.equal(node.nodes.length, 0);257 });258 it('should work when node.pop is a function', function() {259 var node = new Node({type: 'brace'});260 var a = new Node({type: 'a', value: 'foo'});261 var b = new Node({type: 'b', value: 'foo'});262 decorate(node);263 utils.pushNode(node, a);264 utils.pushNode(node, b);265 assert.equal(node.nodes[0].type, 'a');266 assert.equal(node.nodes[1].type, 'b');267 utils.popNode(node);268 utils.popNode(node);269 assert.equal(node.nodes.length, 0);270 });271 });272 describe('.shiftNode', function() {273 it('should throw an error when not a node', function() {274 assert.throws(function() {275 utils.shiftNode();276 });277 });278 it('should shift a node from node.nodes', function() {279 var node = new Node({type: 'brace'});280 var a = new Node({type: 'a', value: 'foo'});281 var b = new Node({type: 'b', value: 'foo'});282 utils.pushNode(node, a);283 utils.pushNode(node, b);284 assert.equal(node.nodes[0].type, 'a');285 assert.equal(node.nodes[1].type, 'b');286 utils.shiftNode(node);287 utils.shiftNode(node);288 assert.equal(node.nodes.length, 0);289 });290 it('should work when node.shift is not a function', function() {291 var node = new Node({type: 'brace'});292 var a = new Node({type: 'a', value: 'foo'});293 var b = new Node({type: 'b', value: 'foo'});294 node.shiftNode = null;295 node.shift = null;296 utils.pushNode(node, a);297 utils.pushNode(node, b);298 assert.equal(node.nodes[0].type, 'a');299 assert.equal(node.nodes[1].type, 'b');300 utils.shiftNode(node);301 utils.shiftNode(node);302 assert.equal(node.nodes.length, 0);303 });304 it('should work when node.shift is a function', function() {305 var node = new Node({type: 'brace'});306 var a = new Node({type: 'a', value: 'foo'});307 var b = new Node({type: 'b', value: 'foo'});308 decorate(node);309 utils.pushNode(node, a);310 utils.pushNode(node, b);311 assert.equal(node.nodes[0].type, 'a');312 assert.equal(node.nodes[1].type, 'b');313 utils.shiftNode(node);314 utils.shiftNode(node);315 assert.equal(node.nodes.length, 0);316 });317 });318 describe('.removeNode', function() {319 it('should throw an error when not a node', function() {320 assert.throws(function() {321 utils.removeNode();322 });323 });324 it('should remove a node from node.nodes', function() {325 var node = new Node({type: 'brace'});326 var a = new Node({type: 'a', value: 'foo'});327 var b = new Node({type: 'b', value: 'foo'});328 utils.pushNode(node, a);329 utils.pushNode(node, b);330 assert.equal(node.nodes[0].type, 'a');331 assert.equal(node.nodes[1].type, 'b');332 utils.removeNode(node, a);333 assert.equal(node.nodes.length, 1);334 utils.removeNode(node, b);335 assert.equal(node.nodes.length, 0);336 });337 it('should work when node.remove is not a function', function() {338 var node = new Node({type: 'brace'});339 var a = new Node({type: 'a', value: 'foo'});340 var b = new Node({type: 'b', value: 'foo'});341 node.removeNode = null;342 node.remove = null;343 utils.pushNode(node, a);344 utils.pushNode(node, b);345 assert.equal(node.nodes[0].type, 'a');346 assert.equal(node.nodes[1].type, 'b');347 utils.removeNode(node, a);348 assert.equal(node.nodes.length, 1);349 utils.removeNode(node, b);350 assert.equal(node.nodes.length, 0);351 });352 it('should work when node.remove is a function', function() {353 var node = new Node({type: 'brace'});354 var a = new Node({type: 'a', value: 'foo'});355 var b = new Node({type: 'b', value: 'foo'});356 decorate(node);357 utils.pushNode(node, a);358 utils.pushNode(node, b);359 assert.equal(node.nodes[0].type, 'a');360 assert.equal(node.nodes[1].type, 'b');361 utils.removeNode(node, a);362 utils.removeNode(node, b);363 assert.equal(node.nodes.length, 0);364 });365 it('should return when node.nodes does not exist', function() {366 assert.doesNotThrow(function() {367 var node = new Node({type: 'brace'});368 utils.removeNode(node, node);369 });370 assert.doesNotThrow(function() {371 var node = new Node({type: 'brace'});372 node.removeNode = null;373 node.remove = null;374 utils.removeNode(node, node);375 });376 });377 it('should return when the given node is not in node.nodes', function() {378 assert.doesNotThrow(function() {379 var node = new Node({type: 'brace'});380 var foo = new Node({type: 'foo'});381 var bar = new Node({type: 'bar'});382 utils.pushNode(node, bar);383 utils.removeNode(node, foo);384 });385 assert.doesNotThrow(function() {386 var node = new Node({type: 'brace'});387 var foo = new Node({type: 'foo'});388 var bar = new Node({type: 'bar'});389 node.removeNode = null;390 node.remove = null;391 utils.pushNode(node, bar);392 utils.removeNode(node, foo);393 });394 });395 });396 describe('.addOpen', function() {397 it('should throw an error when not a node', function() {398 assert.throws(function() {399 utils.addOpen();400 });401 });402 it('should add an open node', function() {403 var node = new Node({type: 'brace'});404 var text = new Node({type: 'text', value: 'foo'});405 utils.addOpen(node, Node);406 assert.equal(node.nodes[0].type, 'brace.open');407 });408 it('should work when node.unshift is a function', function() {409 var node = new Node({type: 'brace'});410 var text = new Node({type: 'text', value: 'foo'});411 decorate(node);412 utils.addOpen(node, Node);413 assert.equal(node.nodes[0].type, 'brace.open');414 });415 it('should work when node.unshift is not a function', function() {416 var node = new Node({type: 'brace'});417 var text = new Node({type: 'text', value: 'foo'});418 node.unshiftNode = null;419 node.unshift = null;420 utils.addOpen(node, Node);421 assert.equal(node.nodes[0].type, 'brace.open');422 });423 it('should take a filter function', function() {424 var node = new Node({type: 'brace'});425 var text = new Node({type: 'text', value: 'foo'});426 utils.addOpen(node, Node, function(node) {427 return node.type !== 'brace';428 });429 assert(!node.nodes);430 });431 it('should use the given value on the open node', function() {432 var node = new Node({type: 'brace'});433 var text = new Node({type: 'text', value: 'foo'});434 utils.addOpen(node, Node, '{');435 assert.equal(node.nodes[0].value, '{');436 });437 });438 describe('.addClose', function() {439 it('should throw an error when not a node', function() {440 assert.throws(function() {441 utils.addClose();442 });443 });444 it('should add a close node', function() {445 var node = new Node({type: 'brace'});446 var text = new Node({type: 'text', value: 'foo'});447 utils.pushNode(node, text);448 utils.addClose(node, Node);449 assert.equal(node.nodes[0].type, 'text');450 assert.equal(node.nodes[1].type, 'brace.close');451 });452 it('should work when node.push is not a function', function() {453 var node = new Node({type: 'brace'});454 var text = new Node({type: 'text', value: 'foo'});455 node.pushNode = null;456 node.push = null;457 utils.pushNode(node, text);458 utils.addClose(node, Node);459 assert.equal(node.nodes[0].type, 'text');460 assert.equal(node.nodes[1].type, 'brace.close');461 });462 it('should work when node.push is a function', function() {463 var node = new Node({type: 'brace'});464 var text = new Node({type: 'text', value: 'foo'});465 decorate(node);466 utils.pushNode(node, text);467 utils.addClose(node, Node);468 assert.equal(node.nodes[0].type, 'text');469 assert.equal(node.nodes[1].type, 'brace.close');470 });471 it('should take a filter function', function() {472 var node = new Node({type: 'brace'});473 var text = new Node({type: 'text', value: 'foo'});474 utils.addClose(node, Node, function(node) {475 return node.type !== 'brace';476 });477 assert(!node.nodes);478 });479 it('should use the given value on the close node', function() {480 var node = new Node({type: 'brace'});481 var text = new Node({type: 'text', value: 'foo'});482 utils.addClose(node, Node, '}');483 assert.equal(node.nodes[0].value, '}');484 });485 });486 describe('.wrapNodes', function() {487 it('should throw an error when not a node', function() {488 assert.throws(function() {489 utils.wrapNodes();490 });491 });492 it('should add an open node', function() {493 var node = new Node({type: 'brace'});494 var text = new Node({type: 'text', value: 'foo'});495 utils.wrapNodes(node, Node);496 assert.equal(node.nodes[0].type, 'brace.open');497 });498 it('should add a close node', function() {499 var node = new Node({type: 'brace'});500 var text = new Node({type: 'text', value: 'foo'});501 utils.pushNode(node, text);502 utils.wrapNodes(node, Node);503 assert.equal(node.nodes[0].type, 'brace.open');504 assert.equal(node.nodes[1].type, 'text');505 assert.equal(node.nodes[2].type, 'brace.close');506 });507 });508 describe('.isEmpty', function() {509 it('should throw an error when not a node', function() {510 assert.throws(function() {511 utils.isEmpty();512 });513 });514 it('should return true node.value is an empty string', function() {515 assert(utils.isEmpty(new Node({type: 'text', value: ''})));516 });517 it('should return true node.value is undefined', function() {518 assert(utils.isEmpty(new Node({type: 'text'})));519 });520 it('should return true when node.nodes is empty', function() {521 var foo = new Node({type: 'foo'});522 var bar = new Node({type: 'text', value: 'bar'});523 utils.pushNode(foo, bar);524 assert(!utils.isEmpty(foo));525 utils.shiftNode(foo);526 assert(utils.isEmpty(foo));527 });528 it('should return true when node.nodes is all non-text nodes', function() {529 var node = new Node({type: 'parent'});530 var foo = new Node({type: 'foo'});531 var bar = new Node({type: 'bar'});532 var baz = new Node({type: 'baz'});533 utils.pushNode(node, foo);534 utils.pushNode(node, bar);535 utils.pushNode(node, baz);536 assert(utils.isEmpty(foo));537 });538 it('should return call a custom function if only one node exists', function() {539 var foo = new Node({type: 'foo'});540 var text = new Node({type: 'text', value: ''});541 utils.pushNode(foo, text);542 assert(utils.isEmpty(foo, node => !node.value));543 });544 it('should return true when only open and close nodes exist', function() {545 var brace = new Node({type: 'brace'});546 var open = new Node({type: 'brace.open'});547 var close = new Node({type: 'brace.close'});548 utils.pushNode(brace, open);549 utils.pushNode(brace, close);550 assert(utils.isEmpty(brace));551 });552 it('should call a custom function on "middle" nodes (1)', function() {553 var brace = new Node({type: 'brace'});554 var open = new Node({type: 'brace.open'});555 var text = new Node({type: 'text', value: ''});556 var close = new Node({type: 'brace.close'});557 utils.pushNode(brace, open);558 utils.pushNode(brace, text);559 utils.pushNode(brace, text);560 utils.pushNode(brace, text);561 utils.pushNode(brace, close);562 assert(utils.isEmpty(brace, function(node) {563 if (node.nodes && node.nodes.length === 0) {564 return true;565 }566 return !utils.value(node);567 }));568 });569 it('should call a custom function on "middle" nodes (2)', function() {570 var brace = new Node({type: 'brace'});571 var open = new Node({type: 'brace.open'});572 var text = new Node({type: 'text', value: ''});573 var close = new Node({type: 'brace.close'});574 utils.pushNode(brace, open);575 utils.pushNode(brace, text);576 utils.pushNode(brace, text);577 utils.pushNode(brace, text);578 utils.pushNode(brace, close);579 assert(!utils.isEmpty(brace, function(node) {580 return node.parent.nodes.length === 0;581 }));582 });583 it('should call a custom function on "middle" nodes (3)', function() {584 var brace = new Node({type: 'brace'});585 var open = new Node({type: 'brace.open'});586 var text = new Node({type: 'text', value: 'foo'});587 var close = new Node({type: 'brace.close'});588 utils.pushNode(brace, open);589 utils.pushNode(brace, text);590 utils.pushNode(brace, close);591 assert(!utils.isEmpty(brace, function(node) {592 if (node.type !== 'text') {593 return false;594 }595 return node.value.trim() === '';596 }));597 });598 it('should call a custom function on "middle" nodes (4)', function() {599 var brace = new Node({type: 'brace'});600 var open = new Node({type: 'brace.open'});601 var empty = new Node({type: 'text', value: ''});602 var text = new Node({type: 'text', value: 'foo'});603 var close = new Node({type: 'brace.close'});604 utils.pushNode(brace, open);605 utils.pushNode(brace, empty);606 utils.pushNode(brace, empty);607 utils.pushNode(brace, empty);608 utils.pushNode(brace, empty);609 utils.pushNode(brace, text);610 utils.pushNode(brace, close);611 assert(!utils.isEmpty(brace, function(node) {612 if (node.type !== 'text') {613 return false;614 }615 return node.value.trim() === '';616 }));617 });618 });619 describe('.isType', function() {620 it('should throw an error when matcher is invalid', function() {621 assert.throws(function() {622 utils.isType(new Node({type: 'foo'}));623 });624 });625 it('should return false if the node is not the given type', function() {626 assert(!utils.isType());627 assert(!utils.isType({}, 'root'));628 });629 it('should return true if the node is the given type', function() {630 assert(utils.isType(ast, 'root'));631 assert(utils.isType(ast.last, 'eos'));632 });633 });634 describe('.isInsideType', function() {635 it('should throw an error when parent is not a node', function() {636 assert.throws(function() {637 utils.isInsideType();638 });639 });640 it('should throw an error when child not a node', function() {641 assert.throws(function() {642 utils.isInsideType(new Node({type: 'foo'}));643 });644 });645 it('should return false when state.inside is not an object', function() {646 var state = {};647 var node = new Node({type: 'brace'});648 assert(!utils.isInsideType(state, 'brace'));649 });650 it('should return false when state.inside[type] is not an object', function() {651 var state = {inside: {}};652 var node = new Node({type: 'brace'});653 assert(!utils.isInsideType(state, 'brace'));654 });655 it('should return true when state has the given type', function() {656 var state = { inside: {}};657 var node = new Node({type: 'brace'});658 utils.addType(state, node);659 assert(utils.isInsideType(state, 'brace'));660 });661 it('should return false when state does not have the given type', function() {662 var state = { inside: {}};663 var node = new Node({type: 'brace'});664 utils.addType(state, node);665 assert(utils.isInsideType(state, 'brace'));666 utils.removeType(state, node);667 assert(!utils.isInsideType(state, 'brace'));668 });669 });670 describe('.isInside', function() {671 it('should throw an error when parent is not a node', function() {672 assert.throws(function() {673 utils.isInside();674 });675 });676 it('should throw an error when child not a node', function() {677 assert.throws(function() {678 utils.isInside(new Node({type: 'foo'}));679 });680 });681 it('should return false when state.inside is not an object', function() {682 var state = {};683 var node = new Node({type: 'brace'});684 assert(!utils.isInside(state, node, 'brace'));685 });686 it('should return false when state.inside[type] is not an object', function() {687 var state = {inside: {}};688 var node = new Node({type: 'brace'});689 assert(!utils.isInside(state, node, 'brace'));690 });691 it('should return true when state has the given type', function() {692 var state = { inside: {}};693 var node = new Node({type: 'brace'});694 utils.addType(state, node);695 assert(utils.isInside(state, node, 'brace'));696 });697 it('should return true when state has one of the given types', function() {698 var state = { inside: {}};699 var node = new Node({type: 'brace'});700 utils.addType(state, node);701 assert(utils.isInside(state, node, ['foo', 'brace']));702 });703 it('should return false when state does not have one of the given types', function() {704 var state = { inside: {}};705 var node = new Node({type: 'brace'});706 utils.addType(state, node);707 assert(!utils.isInside(state, node, ['foo', 'bar']));708 });709 it('should return true when a regex matches a type', function() {710 var state = { inside: {}};711 var node = new Node({type: 'brace'});712 utils.addType(state, node);713 assert(utils.isInside(state, node, /(foo|brace)/));714 });715 it('should return true when the type matches parent.type', function() {716 var state = {};717 var brace = new Node({type: 'brace'});718 var node = new Node({type: 'brace.open'});719 utils.pushNode(brace, node);720 assert(utils.isInside(state, node, 'brace'));721 });722 it('should return true when regex matches parent.type', function() {723 var state = {};724 var brace = new Node({type: 'brace'});725 var node = new Node({type: 'brace.open'});726 utils.pushNode(brace, node);727 assert(utils.isInside(state, node, /(foo|brace)/));728 });729 it('should return false when a regex does not match a type', function() {730 var state = { inside: {}};731 var node = new Node({type: 'brace'});732 utils.addType(state, node);733 assert(!utils.isInside(state, node, /(foo|bar)/));734 });735 it('should return false when type is invalie', function() {736 var state = { inside: {}};737 var node = new Node({type: 'brace'});738 utils.addType(state, node);739 assert(!utils.isInside(state, node, null));740 });741 it('should return false when state does not have the given type', function() {742 var state = { inside: {}};743 var node = new Node({type: 'brace'});744 utils.addType(state, node);745 assert(utils.isInside(state, node, 'brace'));746 utils.removeType(state, node);747 assert(!utils.isInside(state, node, 'brace'));748 });749 });750 describe('.hasType', function() {751 it('should return true if node.nodes has the given type', function() {752 assert(utils.hasType(ast, 'text'));753 assert(!utils.hasType(ast, 'foo'));754 });755 it('should return false when node.nodes does not exist', function() {756 assert(!utils.hasType(new Node({type: 'foo'})));757 });758 });759 describe('.firstOfType', function() {760 it('should throw an error when not a node', function() {761 assert.throws(function() {762 utils.firstOfType();763 });764 });765 it('should get the first node of the given type', function() {766 var node = utils.firstOfType(ast.nodes, 'text');767 assert.equal(node.type, 'text');768 });769 });770 describe('.last', function() {771 it('should get the last node', function() {772 assert.equal(utils.last(ast.nodes).type, 'eos');773 });774 });775 describe('.findNode', function() {776 it('should get the node with the given type', function() {777 var text = utils.findNode(ast.nodes, 'text');778 assert.equal(text.type, 'text');779 });780 it('should get the node matching the given regex', function() {781 var text = utils.findNode(ast.nodes, /text/);782 assert.equal(text.type, 'text');783 });784 it('should get the first matching node', function() {785 var node = utils.findNode(ast.nodes, [/text/, 'bos']);786 assert.equal(node.type, 'bos');787 node = utils.findNode(ast.nodes, [/text/]);788 assert.equal(node.type, 'text');789 });790 it('should get the node at the given index', function() {791 var bos = utils.findNode(ast.nodes, 0);792 assert.equal(bos.type, 'bos');793 var text = utils.findNode(ast.nodes, 1);794 assert.equal(text.type, 'text');795 });796 it('should return null when node does not exist', function() {797 assert.equal(utils.findNode(new Node({type: 'foo'})), null);798 });799 });800 describe('.removeNode', function() {801 it('should throw an error when parent is not a node', function() {802 assert.throws(function() {803 utils.removeNode();804 });805 });806 it('should remove a node from parent.nodes', function() {807 var brace = new Node({type: 'brace'});808 var open = new Node({type: 'brace.open'});809 var foo = new Node({type: 'foo'});810 var bar = new Node({type: 'bar'});811 var baz = new Node({type: 'baz'});812 var qux = new Node({type: 'qux'});813 var close = new Node({type: 'brace.close'});814 utils.pushNode(brace, open);815 utils.pushNode(brace, foo);816 utils.pushNode(brace, bar);817 utils.pushNode(brace, baz);818 utils.pushNode(brace, qux);819 utils.pushNode(brace, close);820 assert.equal(brace.nodes.length, 6);821 assert.equal(brace.nodes[0].type, 'brace.open');822 assert.equal(brace.nodes[1].type, 'foo');823 assert.equal(brace.nodes[2].type, 'bar');824 assert.equal(brace.nodes[3].type, 'baz');825 assert.equal(brace.nodes[4].type, 'qux');826 assert.equal(brace.nodes[5].type, 'brace.close');827 // remove node828 utils.removeNode(brace, bar);829 assert.equal(brace.nodes.length, 5);830 assert.equal(brace.nodes[0].type, 'brace.open');831 assert.equal(brace.nodes[1].type, 'foo');832 assert.equal(brace.nodes[2].type, 'baz');833 assert.equal(brace.nodes[3].type, 'qux');834 assert.equal(brace.nodes[4].type, 'brace.close');835 });836 });837 describe('.isOpen', function() {838 it('should be true if node is an ".open" node', function() {839 var node = new Node({type: 'foo.open'});840 assert(utils.isOpen(node));841 });842 it('should be false if node is not an ".open" node', function() {843 var node = new Node({type: 'foo'});844 assert(!utils.isOpen(node));845 });846 });847 describe('.isClose', function() {848 it('should be true if node is a ".close" node', function() {849 var node = new Node({type: 'foo.close'});850 assert(utils.isClose(node));851 });852 it('should be false if node is not a ".close" node', function() {853 var node = new Node({type: 'foo'});854 assert(!utils.isClose(node));855 });856 });857 describe('.hasOpen', function() {858 it('should throw an error when not a node', function() {859 assert.throws(function() {860 utils.hasOpen();861 });862 });863 it('should be true if node has an ".open" node', function() {864 var parent = new Node({type: 'foo'});865 var node = new Node({type: 'foo.open'});866 utils.pushNode(parent, node);867 assert(utils.hasOpen(parent));868 });869 it('should be false if does not have an ".open" node', function() {870 var parent = new Node({type: 'foo'});871 assert(!utils.hasOpen(parent));872 });873 });874 describe('.hasClose', function() {875 it('should throw an error when not a node', function() {876 assert.throws(function() {877 utils.hasClose();878 });879 });880 it('should be true if node has a ".close" node', function() {881 var parent = new Node({type: 'foo'});882 var open = new Node({type: 'foo.open'});883 var close = new Node({type: 'foo.close'});884 utils.pushNode(parent, open);885 utils.pushNode(parent, close);886 assert(utils.hasClose(parent));887 });888 it('should be false if does not have a ".close" node', function() {889 var parent = new Node({type: 'foo'});890 assert(!utils.hasClose(parent));891 });892 });893 describe('.hasOpenAndClose', function() {894 it('should throw an error when not a node', function() {895 assert.throws(function() {896 utils.hasOpenAndClose();897 });898 });899 it('should be true if node has ".open" and ".close" nodes', function() {900 var parent = new Node({type: 'foo'});901 var open = new Node({type: 'foo.open'});902 var close = new Node({type: 'foo.close'});903 utils.pushNode(parent, open);904 utils.pushNode(parent, close);905 assert(utils.hasOpenAndClose(parent));906 });907 it('should be false if does not have a ".close" node', function() {908 var parent = new Node({type: 'foo'});909 var open = new Node({type: 'foo.open'});910 utils.pushNode(parent, open);911 assert(!utils.hasOpenAndClose(parent));912 });913 it('should be false if does not have an ".open" node', function() {914 var parent = new Node({type: 'foo'});915 var close = new Node({type: 'foo.close'});916 utils.pushNode(parent, close);917 assert(!utils.hasOpenAndClose(parent));918 });919 });920 describe('.pushNode', function() {921 it('should throw an error when parent is not a node', function() {922 assert.throws(function() {923 utils.pushNode();924 });925 });926 it('should add a node to `node.nodes`', function() {927 var node = new Node({type: 'foo'});928 utils.pushNode(ast, node);929 assert.equal(ast.last.type, 'foo');930 });931 it('should set the parent on the given node', function() {932 var node = new Node({type: 'foo'});933 utils.pushNode(ast, node);934 assert.equal(node.parent.type, 'root');935 });936 it('should set the parent.nodes as node.siblings', function() {937 var node = new Node({type: 'foo'});938 assert.equal(node.siblings, null);939 utils.pushNode(ast, node);940 assert.equal(node.siblings.length, 8);941 });942 });943 describe('.addType', function() {944 it('should throw an error when state is not given', function() {945 assert.throws(function() {946 utils.addType();947 });948 });949 it('should throw an error when a node is not passed', function() {950 assert.throws(function() {951 utils.addType({});952 });953 });954 it('should add the type to the state.inside array', function() {955 var state = {};956 var node = new Node({type: 'brace'});957 utils.addType(state, node);958 assert(state.inside);959 assert(state.inside.brace);960 assert.equal(state.inside.brace.length, 1);961 });962 it('should add the type based on parent.type', function() {963 var state = {};964 var parent = new Node({type: 'brace'});965 var node = new Node({type: 'brace.open'});966 utils.pushNode(parent, node);967 utils.addType(state, node);968 assert(state.inside);969 assert(state.inside.brace);970 assert.equal(state.inside.brace.length, 1);971 });972 });973 describe('.removeType', function() {974 it('should throw an error when state is not given', function() {975 assert.throws(function() {976 utils.removeType();977 });978 });979 it('should throw an error when a node is not passed', function() {980 assert.throws(function() {981 utils.removeType({});982 });983 });984 it('should add a state.inside object', function() {985 var state = {};986 var node = new Node({type: 'brace'});987 utils.addType(state, node);988 assert(state.inside);989 });990 it('should add a type array to the state.inside object', function() {991 var state = {};992 var node = new Node({type: 'brace'});993 utils.addType(state, node);994 assert(state.inside);995 assert(Array.isArray(state.inside.brace));996 });997 it('should add the node to the state.inside type array', function() {998 var state = {};999 var node = new Node({type: 'brace'});1000 utils.addType(state, node);1001 assert(state.inside);1002 assert(state.inside.brace);1003 assert.equal(state.inside.brace.length, 1);1004 utils.removeType(state, node);1005 assert.equal(state.inside.brace.length, 0);1006 });1007 it('should use a type array if it already exists', function() {1008 var state = { inside: { brace: [new Node({type: 'brace.open'})] }};1009 var node = new Node({type: 'brace'});1010 utils.addType(state, node);1011 assert(state.inside);1012 assert(state.inside.brace);1013 assert.equal(state.inside.brace.length, 2);1014 utils.removeType(state, node);1015 assert.equal(state.inside.brace.length, 1);1016 });1017 it('should remove the type based on parent.type', function() {1018 var state = { inside: { brace: [new Node({type: 'brace.open'})] }};1019 var parent = new Node({type: 'brace'});1020 var node = new Node({type: 'brace.open'});1021 utils.pushNode(parent, node);1022 utils.addType(state, node);1023 assert(state.inside);1024 assert(state.inside.brace);1025 assert.equal(state.inside.brace.length, 2);1026 utils.removeType(state, node);1027 assert.equal(state.inside.brace.length, 1);1028 });1029 it('should throw an error when state.inside does not exist', function() {1030 var state = {};1031 var node = new Node({type: 'brace'});1032 assert.throws(function() {1033 utils.removeType(state, node);1034 });1035 });...
EMwave.js
Source:EMwave.js
...101 [],102 [],103 [],104 ]105 function pushNode(i, dirX, dirY, array) {106 array.push({107 x: physics.xOffset,108 y: physics.yOffset,109 Vx: dirX,110 Vy: dirY,111 returnCycle: i,112 });113 }114 //initialize data in node115 for (let i = 0; i < physics.totalNodes; i++) {116 pushNode(i, 1, 0, node[0]);117 pushNode(i, 0.92, 0.38, node[1]);118 pushNode(i, 0.7, 0.7, node[2]);119 pushNode(i, 0.38, 0.92, node[3]);120 pushNode(i, 0, 1, node[4]);121 pushNode(i, -0.38, 0.92, node[5]);122 pushNode(i, -0.7, 0.7, node[6]);123 pushNode(i, -0.92, 0.38, node[7]);124 pushNode(i, -1, 0, node[8]);125 pushNode(i, -0.92, -0.38, node[9]);126 pushNode(i, -0.7, -0.7, node[10]);127 pushNode(i, -0.38, -0.92, node[11]);128 pushNode(i, 0, -1, node[12]);129 pushNode(i, 0.38, -0.92, node[13]);130 pushNode(i, 0.7, -0.7, node[14]);131 pushNode(i, 0.92, -0.38, node[15]);132 }133 function drawLines() {134 function fieldLineLoop(node) { //lines135 i = node.length;136 ctx.moveTo(node[i - 1].x, node[i - 1].y);137 while (i--) {138 ctx.lineTo(node[i].x, node[i].y);139 node[i].x += node[i].Vx * physics.speed; //move node140 node[i].y += node[i].Vy * physics.speed; //move node141 if (node[i].returnCycle < physics.cycle) { //check for return142 node.splice(i, 1);143 pushNode(physics.cycle + physics.totalNodes - 1, node[i].Vx, node[i].Vy, node);144 }145 }146 }147 //draw 16 legs148 ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);149 ctx.beginPath();150 for (let i = 0; i < 16; i++) {151 fieldLineLoop(node[i]);152 }153 ctx.strokeStyle = "#fff";154 ctx.lineWidth = 6;155 ctx.stroke();156 }157 function drawCircles() {158 function fieldLineLoop(node) { //lines159 i = node.length;160 while (i--) {161 node[i].x += node[i].Vx * physics.speed; //move node162 node[i].y += node[i].Vy * physics.speed; //move node163 if (node[i].returnCycle < physics.cycle) { //check for return164 node.splice(i, 1);165 pushNode(physics.cycle + physics.totalNodes - 1, node[i].Vx, node[i].Vy, node);166 }167 }168 }169 for (let i = 0; i < 16; i++) {170 fieldLineLoop(node[i]);171 }172 const len = node[0].length - 1173 ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);174 ctx.beginPath();175 for (let j = 0; j < len; j++) {176 if (!(j % 2)) {177 ctx.moveTo(node[15][j].x, node[15][j].y)178 for (let i = 0; i < 16; i++) {179 ctx.lineTo(node[i][j].x, node[i][j].y)...
Tree.js
Source:Tree.js
...88 // ä¸åºéå (ä¸åºéåæ¯å
éåå·¦åæ ï¼ç¶å访é®æ ¹èç¹ï¼ç¶åéåå³åæ ã)89 inOrder(node) {90 let stack = [];91 // ä¸åºéåéå½åæ³92 function pushNode(node) {93 if (node !== null) {94 if (node.left !== null) {95 pushNode(node.left)96 }97 stack.push(node.value);98 if (node.right !== null) {99 pushNode(node.right);100 }101 }102 }103 // ä¸åºéåè¿ä»£ 使ç¨æ 104 function pushNodeStack(node) {105 let middleStack = [];106 let current = node;107 let parent = null;108 while (current !== null || middleStack.length > 0) {109 if (current != null) {110 middleStack.push(current);111 current = current.left;112 } else {113 current = middleStack.pop();114 stack.push(current.value);115 current = current.right;116 }117 } 118 }119 return stack;120 }121 // ååºéå å
æ ¹ å¨å·¦ å³ å
访é®æ ¹èç¹ãéåå·¦åæ ãæåå³åæ 122 preOrder() {123 let stack = [];124 function pushNode(root) {125 if (root) {126 stack.push(root.value);127 if (root.left) {128 pushNode(root.left);129 }130 if (root.right) {131 pushNode(root.right);132 }133 }134 }135 pushNode2(this.root);136 function pushNode2(root) {137 let middle = [];138 let p = root;139 while (middle.length > 0 || p) {140 if (p) {141 // å
å
¥æ ¹èç¹142 stack.push(p.value);143 middle.push(p);144 p = p.left;145 } else {146 p = middle.pop();147 p = p.right;148 }149 }150 }151 }152 // ååºéå å
å·¦ åå³ æåæ ¹153 // [5, 8, 7, 19, 12, 23, 87, 9]154 postOrder() {155 let stack = [];156 // éå½157 function pushNode(root) {158 if (root !== null) {159 if (root.left !== null) {160 pushNode(root.left);161 }162 if (root.right !== null) {163 pushNode(root.right);164 }165 stack.push(root.value);166 }167 }168 function pushNode2(root) {169 let middle = [];170 let current = root;171 let prev = null;172 while (current || middle.length > 0) {173 if (current) {174 middle.push(current);175 current = current.left;176 } else {177 current = middle.pop();178 // 没æå³åæ æè
å访é®è¿179 if (!current.right || current.right === prev) {180 stack.push(current.value);181 prev = current;182 current = null;183 } else {184 middle.push(current);185 middle.push(current.right);186 current = current.right.left;187 }188 }189 }190 }191 pushNode2(this.root)192 return stack;193 }194 // å±åºéåäºåæ 195 // BFS éåå®ç° 广度ä¼å
196 // [9, 7, 87, 5, 8, 23, 12, 19]197 levelOrder() {198 let stack = [];199 function pushNode(root) {200 let middle = [];201 middle.push(root);202 while (middle.length > 0) {203 let node = middle.shift();204 stack.push(node.value);205 if (node.left) {206 middle.push(node.left);207 }208 if (node.right) {209 middle.push(node.right)210 }211 }212 console.log(stack)213 }214 pushNode(this.root);215 }216 // DFS 深度ä¼å
217 deepOrder() {218 let stack = [];219 function pushNode(root) {220 let middle = [];221 middle.push(root);222 while (middle.length > 0) {223 let node = middle.pop();224 stack.push(node.value);225 if (node.right) {226 middle.push(node.right);227 }228 if (node.left) {229 middle.push(node.left)230 }231 }232 }233 pushNode(this.root);234 }235}236const t1 = new BST();237t1.insert(9);238t1.insert(7);239t1.insert(8);240t1.insert(5);241t1.insert(87);242t1.insert(23);243t1.insert(12);244t1.insert(19);245console.log(t1);246// t1.inOrder(t1.root);247t1.deepOrder();
parser.js
Source:parser.js
...66 return node67 },68 identifier: function(inCode) {69 if (this.a.length) {70 this.pushNode(inCode, 'identifier');71 }72 return inCode;73 },74 findChildren: function(inNode) {75 var children = this.processTokens();76 // attach a parent pointer to each child77 for (var i = 0, c; c = children[i]; i++) {78 c.parent = inNode;79 c.index = i;80 }81 // update node with correct end/height82 inNode.children = children;83 inNode.end = this.lastToken.end;84 inNode.height = this.lastToken.line - inNode.line;85 },86 processArray: function(inCode, inToken) {87 this.identifier(inCode);88 this.findChildren(this.pushNode(inCode, 'array'));89 },90 processBlock: function(inCode, inToken) {91 this.identifier(inCode);92 this.findChildren(this.pushNode(inCode, 'block'));93 },94 processArguments: function(inCode, inToken) {95 this.identifier(inCode);96 var kind = 'association';97 if (this.lastToken.kind == "identifier" || this.lastToken.token == "function") {98 kind = 'argument-list';99 }100 this.findChildren(this.pushNode(inCode, kind));101 },102 processTokens: function(inKind) {103 var mt, t, code = [];104 while (mt = this.next()) {105 t = mt.token;106 //107 if (mt.kind == "ws") {108 continue;109 }110 else if (mt.kind == "literal")111 this.pushNode(code, mt.kind, mt, mt.delimiter);112 else if (mt.kind == "string")113 this.pushNode(code, mt.kind, mt);114 else if (mt.kind == "comment" || mt.kind=="keyword") {115 this.identifier(code);116 this.pushNode(code, mt.kind, mt);117 }118 //119 else if (t == '=' || t == ':') { 120 this.identifier(code);121 this.pushNode(code, "assignment", mt);122 }123 //124 else if (t == ';' || t == ',')125 this.identifier(code);126 //127 else if (t == '[')128 this.processArray(code, mt);129 else if (t == ']') {130 this.lastToken = mt;131 return this.identifier(code);132 }133 //134 else if (t == '{')135 this.processBlock(code, mt);...
10866_덱.js
Source:10866_덱.js
1const fs = require("fs");2const filePath = process.platform === "linux" ? "/dev/stdin" : "../input.txt";3class Node {4 constructor(initValue) {5 this.value = initValue;6 this.prev = null;7 this.next = null;8 }9}10class DoubleLinkedList {11 // headê° back, tailì´ front12 constructor() {13 this.head = null;14 this.tail = null;15 this.len = 0;16 }17 push_front(pushValue) {18 const pushNode = new Node(pushValue);19 if (this.len) {20 this.tail.next = pushNode;21 pushNode.prev = this.tail;22 this.tail = pushNode;23 } else {24 this.head = pushNode;25 this.tail = pushNode;26 }27 this.len += 1;28 }29 push_back(pushValue) {30 const pushNode = new Node(pushValue);31 if (this.len) {32 pushNode.next = this.head;33 this.head.prev = pushNode;34 this.head = pushNode;35 } else {36 this.head = pushNode;37 this.tail = pushNode;38 }39 this.len += 1;40 }41 pop_front() {42 if (this.len === 0) return -1;43 const frontValue = this.tail.value;44 if (this.len === 1) {45 this.head = null;46 this.tail = null;47 }48 if (this.len >= 2) {49 this.tail.prev.next = null;50 this.tail = this.tail.prev;51 }52 this.len -= 1;53 return frontValue;54 }55 pop_back() {56 if (this.len === 0) return -1;57 const backValue = this.head.value;58 if (this.len === 1) {59 this.head = null;60 this.tail = null;61 }62 if (this.len >= 2) {63 this.head.next.prev = null;64 this.head = this.head.next;65 }66 this.len -= 1;67 return backValue;68 }69 size() {70 return this.len;71 }72 empty() {73 return Number(this.len === 0);74 }75 front() {76 return this.len ? this.tail.value : -1;77 }78 back() {79 return this.len ? this.head.value : -1;80 }81}82let [n, ...input] = fs.readFileSync(filePath).toString().trim().split("\n");83const doubleLinkedList = new DoubleLinkedList();84console.log(solution(input, doubleLinkedList));85function solution(input, doubleLinkedList) {86 let answer = "";87 input.forEach((line) => {88 let [command, num] = line.split(" ");89 num = Number(num);90 if (command === "push_back") doubleLinkedList.push_back(num);91 if (command === "push_front") doubleLinkedList.push_front(num);92 if (command === "pop_front") answer += `${doubleLinkedList.pop_front()}\n`;93 if (command === "pop_back") answer += `${doubleLinkedList.pop_back()}\n`;94 if (command === "size") answer += `${doubleLinkedList.size()}\n`;95 if (command === "empty") answer += `${doubleLinkedList.empty()}\n`;96 if (command === "front") answer += `${doubleLinkedList.front()}\n`;97 if (command === "back") answer += `${doubleLinkedList.back()}\n`;98 });99 return answer;...
util-order.js
Source:util-order.js
...4export function preorderTraversal(root) {5 if (!root) return []6 // éåçç»æ7 const result = []8 pushNode(root)9 10 function pushNode(node) {11 result.push(node.val)12 if (node.left) pushNode(node.left)13 if (node.right) pushNode(node.right)14 }15 return result16}17export function inorderTraversal(root) {18 if (!root) return []19 // éåçç»æ20 const result = []21 pushNode(root)22 function pushNode(node) {23 if (node.left) pushNode(node.left)24 result.push(node.val)25 if (node.right) pushNode(node.right)26 }27 return result28}29export function nextorder(root) {30 if (!root) return []31 // éåçç»æ32 const result = []33 pushNode(root)34 function pushNode(node) {35 if (node.left) pushNode(node.left)36 if (node.right) pushNode(node.right)37 result.push(node.val)38 }39 return result...
LURCache.test.js
Source:LURCache.test.js
2const LRUCache = require('../LRUCache')3describe('LURCache', () => {4 it('should return latest key when the node is pushed', () => {5 const cache = new LRUCache()6 cache.pushNode('key1', 1)7 cache.pushNode('key2', 2)8 cache.pushNode('key3', 3)9 cache.pushNode('key4', 4)10 cache.pushNode('key5', 5)11 cache.pushNode('key6', 6)12 assert.strictEqual(cache.head.key, 'key6')13 })14 it('should return latest used key when the node is used recently', () => {15 const cache = new LRUCache()16 cache.pushNode('key1', 1)17 cache.pushNode('key2', 2)18 cache.pushNode('key3', 3)19 cache.pushNode('key4', 4)20 cache.pushNode('key5', 5)21 cache.getNode('key2')22 assert.strictEqual(cache.head.key, 'key2')23 })...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.pushNode('document.body');7 await page.popNode();8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 await page.pushNode('document.body');16 await page.popNode();17 await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21 const browser = await chromium.launch();22 const context = await browser.newContext();23 const page = await context.newPage();24 await page.pushNode('document.body');25 const bodyHandle = await page.evaluateHandle(() => document.body);26 console.log(bodyHandle);27 await page.popNode();28 await browser.close();29})();30const { chromium } = require('playwright');31(async () => {32 const browser = await chromium.launch();33 const context = await browser.newContext();34 const page = await context.newPage();35 await page.pushNode('document.body');36 const body = await page.evaluate(() => document.body);37 console.log(body);
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.keyboard.pushNode('a');7 await page.keyboard.pushNode('b');8 await page.keyboard.pushNode('c');9 await page.keyboard.press('Enter');10 await browser.close();11})();12#### keyboard.down(key[, options])13#### keyboard.press(key[, options])14#### keyboard.up(key)15#### keyboard.insertText(text)16#### keyboard.pushNode(node)17#### keyboard.down(key[, options])18#### keyboard.press(key[, options])19#### keyboard.up(key)20#### keyboard.insertText(text)21#### keyboard.pushNode(node)22#### keyboard.down(key[, options])
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const element = await page.$('text=Get Started');7 await element._clickablePoint();8 await page.evaluate(element => element.click(), element);9 await browser.close();10})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.evaluate(() => {7 const input = document.querySelector('input[name=q]');8 const inputBox = input._shadowRoot.querySelector('input');9 inputBox._pushNode('value', 'Hello World!');10 });11 await page.screenshot({ path: `example.png` });12 await browser.close();13})();14#### elementHandle._pushNode(name, value)
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.evaluate(() => {7 const input = document.createElement('input');8 input.type = 'text';9 input.id = 'myinput';10 input.value = 'hello world';11 document.body.appendChild(input);12 });13 await page.screenshot({ path: `example.png` });14 await browser.close();15})();16const { chromium } = require('playwright');17(async () => {18 const browser = await chromium.launch({ headless: false });19 const context = await browser.newContext();20 const page = await context.newPage();21 await page.evaluate(() => {22 const input = document.createElement('input');23 input.type = 'text';24 input.id = 'myinput';25 input.value = 'hello world';26 document.body.appendChild(input);27 });28 await page.screenshot({ path: `example.png` });29 await browser.close();30})();31const { chromium } = require('playwright');32(async () => {33 const browser = await chromium.launch({ headless: false });34 const context = await browser.newContext();35 const page = await context.newPage();36 await page.evaluate(() => {37 const input = document.createElement('input');38 input.type = 'text';39 input.id = 'myinput';40 input.value = 'hello world';41 document.body.appendChild(input);42 });43 await page.screenshot({ path: `example.png` });44 await browser.close();45})();46const { chromium } = require('playwright');47(async () => {48 const browser = await chromium.launch({ headless: false });49 const context = await browser.newContext();
Using AI Code Generation
1const {chromium} = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await page.evaluate(() => {6 window.__playwright__internal__pushNode({7 attributes: {8 style: 'background-color: red; width: 100px; height: 100px;',9 },10 });11 });12 await page.screenshot({path: `example.png`});13 await browser.close();14})();15[MIT](LICENSE)
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.evaluate(() => {7 const div = document.createElement('div');8 div.id = 'myDiv';9 document.body.appendChild(div);10 });11 const myDiv = await page.$('#myDiv');12 await myDiv.evaluate(div => {13 div.innerHTML = 'Hello';14 });15 const value = await myDiv.evaluate(div => div.innerHTML);16 console.log(value);17 await browser.close();18})();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!