Spaces:
Running
Running
File size: 6,223 Bytes
0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 776a711 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 776a711 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f 0deb5b7 c0a630f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
/**
* @fileoverview ChemWriter integration with Gradio interface
* Handles bidirectional synchronization between ChemWriter editor and Gradio textbox
* @author Manny Cortes ('manny@derifyai.com')
* @version 0.3.0
*/
// ============================================================================
// GLOBAL VARIABLES
// ============================================================================
/** @type {Object|null} The ChemWriter editor instance */
let editor = null;
let chemwriter = null;
// ============================================================================
// CONSTANTS
// ============================================================================
/** @const {string} Default SMILES for initial molecule (ethanol) */
const DEFAULT_SMILES = "CN(C)CCC1=CNC2=C1C(=CC=C2)OP(=O)(O)O";
/** @const {string} CSS selector for the Gradio SMILES input element */
const SMILES_INPUT_SELECTOR = "#smiles_input textarea, #smiles_input input";
/** @const {string} CSS selector for the Gradio Mol file input element */
const MOL_INPUT_SELECTOR = "#mol_input textarea, #mol_input input";
/** @const {string} CSS selector for the Gradio search button */
const SEARCH_BUTTON_SELECTOR = "#search_btn";
/** @const {number} Delay for paste event handling (ms) */
const PASTE_DELAY = 50;
/** @const {number} Delay for initialization retry (ms) */
const INIT_RETRY_DELAY = 250;
/** @const {string[]} Events to trigger for Gradio change detection */
const GRADIO_CHANGE_EVENTS = ["input", "change"];
// ============================================================================
// CORE INITIALIZATION
// ============================================================================
/**
* Initializes ChemWriter editor and sets up event handlers
*/
function initializeChemWriter() {
try {
setupSmilesTextboxEventListeners();
setupChemWriterEventListeners();
editor.setSMILES(DEFAULT_SMILES);
// search after the rest of the gradio components load
setTimeout(() => document.getElementById("search_btn")?.click(), 500);
console.log("ChemWriter initialized successfully");
} catch (error) {
console.error("Error initializing ChemWriter:", error);
}
}
// ============================================================================
// GRADIO AND CHEMWRITER INTEGRATION
// ============================================================================
/**
* Updates the mol_input Gradio textbox with a mol file string
* Triggers appropriate events to ensure Gradio detects the change
*/
function updateGradioTextbox() {
try {
const molTextbox = document.querySelector(MOL_INPUT_SELECTOR);
const molFile = editor?.getMolfile();
molTextbox.value = molFile;
// Trigger events to ensure Gradio detects the change
GRADIO_CHANGE_EVENTS.forEach((eventType) => {
const event = new Event(eventType, {
bubbles: true,
cancelable: true,
});
molTextbox.dispatchEvent(event);
});
} catch (error) {
console.error("Error updating Gradio textbox:", error);
}
}
/**
* Updates the ChemWriter editor with a SMILES string from the textbox
* @param {string} smiles - The SMILES string to display in ChemWriter
*/
function updateChemWriterFromTextbox(smiles) {
try {
smiles = smiles.trim();
editor?.setSMILES(smiles);
} catch (error) {
console.error("Error updating ChemWriter from textbox:", error);
}
}
// ============================================================================
// UI MONITORING
// ============================================================================
function setupSmilesTextboxEventListeners() {
const textbox = document.querySelector(SMILES_INPUT_SELECTOR);
if (!textbox) {
return;
}
textbox.addEventListener("input", handleTextboxChange);
textbox.addEventListener("change", handleTextboxChange);
textbox.addEventListener("paste", handleTextboxPaste);
}
function setupChemWriterEventListeners() {
window.addEventListener("resize", () => editor.jd());
editor.addEventListener('document-edited', updateGradioTextbox);
}
/**
* Handles textbox change events
* @param {Event} event - The change event
*/
function handleTextboxChange(event) {
updateChemWriterFromTextbox(event.target.value);
}
/**
* Handles textbox paste events with a delay to ensure content is available
* @param {Event} event - The paste event
*/
function handleTextboxPaste(event) {
setTimeout(() => {
updateChemWriterFromTextbox(event.target.value);
}, PASTE_DELAY);
}
// ============================================================================
// PUBLIC API
// ============================================================================
/**
* Sets ChemWriter SMILES string
* @param {string} smiles - The SMILES string to set
* @public
*/
window.setCWSmiles = function (smiles) {
updateChemWriterFromTextbox(smiles);
};
/**
* Clears both ChemWriter and Gradio textbox
* @public
*/
window.clearCW = function () {
editor.setMolfile('\nCWRITER06142521562D\nCreated with ChemWriter - https://chemwriter.com\n 0 0 0 0 0 0 0 0 0 0999 V2000\nM END');
};
// ============================================================================
// INITIALIZATION LOGIC
// ============================================================================
/**
* Checks if ChemWriter library is loaded and initializes ChemWriter editor
*/
function initializeWhenReady() {
chemwriter = window?.chemwriter;
// The ChemWriter library normally sets up a window load event listener: window.addEventListener("load", function(){Z.De()}, false)
// However, due to race conditions, the "load" event listener may not be added or triggered in time for proper initialization.
// So we call the initialization function directly here.
chemwriter?.System?.De();
editor = chemwriter?.components?.editor;
if (typeof chemwriter?.System?.De !== "undefined" && typeof editor !== "undefined") {
console.log("ChemWriter library loaded, initializing...");
chemwriter.System.ready(initializeChemWriter);
} else {
console.log("ChemWriter library not ready, retrying...");
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
}
}
initializeWhenReady();
|