From 1093c5f39c3245f03a26e5a88b466e7328d6ff81 Mon Sep 17 00:00:00 2001 From: atanas Date: Fri, 19 Jul 2024 22:42:27 +0400 Subject: [PATCH] Helm: placeholders, WIP --- HELM/source/helm/App.ts | 96 ++++++----- HELM/source/helm/Interface.ts | 4 +- HELM/source/helm/MonomerExplorer.ts | 252 ++++++++++++++++++---------- HELM/source/helm/Monomers.ts | 157 ++++++++--------- HELM/source/package-lock.json | 25 ++- HELM/source/src/types/org-helm.ts | 63 ++++--- 6 files changed, 357 insertions(+), 240 deletions(-) diff --git a/HELM/source/helm/App.ts b/HELM/source/helm/App.ts index 385f44f..a8d08c3 100644 --- a/HELM/source/helm/App.ts +++ b/HELM/source/helm/App.ts @@ -27,7 +27,7 @@ import type {DojoType} from '@datagrok-libraries/js-draw-lite/src/types/dojo'; import type {JSDraw2ModuleType, ScilModuleType} from '@datagrok-libraries/js-draw-lite/src/types'; -import type {IAppOptions, OrgType} from '../src/types/org-helm'; +import type {IAppOptions, IRuleSet, OrgType} from '../src/types/org-helm'; import type {IPageForm, Page} from '@datagrok-libraries/js-draw-lite/page/Page'; import type {PageTab} from '@datagrok-libraries/js-draw-lite/page/Page.Tab'; import type {MonomerExplorer} from './MonomerExplorer'; @@ -70,18 +70,18 @@ export class App { private readonly T: string; private readonly options: Partial; public readonly toolbarheight: number; - public mex: MonomerExplorer; - public canvas: Editor; + public mex: MonomerExplorer | null; + public canvas: Editor | null; public sequence: any; - public notation: HTMLElement; - public properties: Form; - public structureview: Editor; - private page: Page; - private treediv: HTMLDivElement; - private handle: HTMLDivElement; - private canvasform: IPageForm; - private sequencebuttons: any[]; - private tabs: PageTab; + public notation: HTMLElement | null; + public properties: Form | null; + public structureview: Editor | null; + private page!: Page; + private treediv!: HTMLDivElement; + private handle!: HTMLDivElement; + private canvasform!: IPageForm; + private sequencebuttons!: any[]; + private tabs!: PageTab; /** @@ -112,12 +112,12 @@ export class App { * </script> * **/ - constructor(parent: HTMLElement | string, options) { + constructor(parent: HTMLElement | string, options: Partial = {}) { this.T = "APP"; this.toolbarheight = 30; - if (typeof (parent) == "string") - parent = scil.byId(parent); + const parentEl: HTMLElement = typeof (parent) == "string" ? scil.byId(parent) : parent; + this.mex = null; this.canvas = null; this.sequence = null; @@ -136,7 +136,7 @@ export class App { org.helm.webeditor.Monomers.cleanupurl = this.options.monomercleanupurl; if (this.options.rulesurl != null) { - scil.Utils.ajax(this.options.rulesurl, function(ret) { + scil.Utils.ajax(this.options.rulesurl, function(ret: any) { if (ret.rules != null) ret = ret.rules; org.helm.webeditor.RuleSet.loadDB(ret); @@ -145,14 +145,14 @@ export class App { if (this.options.monomersurl != null) { const me = this; - scil.Utils.ajax(this.options.monomersurl, function(ret) { + scil.Utils.ajax(this.options.monomersurl, function(ret: any) { if (ret.monomers != null) ret = ret.monomers; org.helm.webeditor.Monomers.loadDB(ret, me.options.monomerfun); - me.init(parent); + me.init(parentEl); }); } else { - this.init(parent); + this.init(parentEl); } }; @@ -162,8 +162,8 @@ export class App { */ calculateSizes() { const d = dojo.window.getBox(); - if (this.options.topmargin > 0) - d.h -= this.options.topmargin; + if (this.options.topmargin! > 0) + d.h -= this.options.topmargin!; let leftwidth = 0; if (this.page != null && this.page.explorer != null && this.page.explorer.left != null) @@ -185,16 +185,16 @@ export class App { * Intialize the App (internal use) * @function init */ - init(parent) { + init(parent: HTMLElement) { const me = this; const sizes = this.calculateSizes(); const tree = { - caption: this.options.topmargin > 0 ? null : "Palette", + caption: this.options.topmargin! > 0 ? null : "Palette", marginBottom: "2px", - marginTop: this.options.topmargin > 0 ? "17px" : null, - onresizetree: function(width) { me.resizeWindow(); }, - onrender: function(div) { + marginTop: this.options.topmargin! > 0 ? "17px" : null, + onresizetree: function(width: number) { me.resizeWindow(); }, + onrender: function(div: HTMLDivElement) { me.treediv = div; me.createPalette(div, sizes.leftwidth - 10, sizes.height); } @@ -210,10 +210,10 @@ export class App { //caption: "Canvas", type: "custom", marginBottom: "2px", - oncreate: function(div) { me.createCanvas(div, sizes.rightwidth, sizes.topheight); } - }); + oncreate: function(div: HTMLDivElement) { me.createCanvas(div, sizes.rightwidth, sizes.topheight); } + })!; - this.handle = this.page.addResizeHandle(function(delta) { return me.onresize(delta); }, 8); + this.handle = this.page.addResizeHandle(function(delta: number) { return me.onresize(delta); }, 8); this.sequencebuttons = [ {label: "Format", type: "select", items: ["", "RNA", "Peptide"], key: "format"}, @@ -227,7 +227,7 @@ export class App { type: "custom", tabkey: "sequence", buttons: this.options.sequenceviewonly ? null : this.sequencebuttons, - oncreate: function(div) { me.createSequence(div, sizes.rightwidth, sizes.bottomheight); } + oncreate: function(div: HTMLDivElement) { me.createSequence(div, sizes.rightwidth, sizes.bottomheight); } }); this.tabs.addForm({ @@ -239,24 +239,24 @@ export class App { {src: scil.Utils.imgSrc("img/add.gif"), label: "Append", title: "Append HELM Notation", onclick: function() { me.updateCanvas("notation", true); }}, {src: scil.Utils.imgSrc("img/tick.gif"), label: "Validate", title: "Validate HELM Notation", onclick: function() { me.validateHelm(); }} ], - oncreate: function(div) { me.createNotation(div, sizes.rightwidth, sizes.bottomheight); } + oncreate: function(div: HTMLDivElement) { me.createNotation(div, sizes.rightwidth, sizes.bottomheight); } }); this.tabs.addForm({ caption: "Properties", type: "custom", tabkey: "properties", - oncreate: function(div) { me.createProperties(div, sizes.rightwidth, sizes.bottomheight); } + oncreate: function(div: HTMLDivElement) { me.createProperties(div, sizes.rightwidth, sizes.bottomheight); } }); this.tabs.addForm({ caption: "Structure View", type: "custom", tabkey: "structureview", - oncreate: function(div) { me.createStructureView(div, sizes.rightwidth, sizes.bottomheight); } + oncreate: function(div: HTMLDivElement) { me.createStructureView(div, sizes.rightwidth, sizes.bottomheight); } }); - scil.connect(window, "onresize", function(e) { me.resizeWindow(); }); + scil.connect(window, "onresize", function(_e: any) { me.resizeWindow(); }); } validateHelm() { @@ -265,19 +265,19 @@ export class App { return; } - const url = this.options.validateurl; + const url: string = this.options.validateurl!; if (scil.Utils.isNullOrEmpty(url)) { scil.Utils.alert("The validation url is not configured yet"); return; } this.setNotationBackgroundColor("white"); - const helm = scil.Utils.getInnerText(this.notation); + const helm = scil.Utils.getInnerText(this.notation!); if (scil.Utils.isNullOrEmpty(helm)) return; const me = this; - scil.Utils.ajax(url, function(ret) { + scil.Utils.ajax(url, function(ret: any) { me.setNotationBackgroundColor(ret.valid ? "#9fc" : "#fcf"); }, {helm: helm}); } @@ -287,6 +287,9 @@ export class App { * @function resizeWindow */ resizeWindow() { + if (!this.canvas || !this.properties || !this.structureview || !this.mex || !this.notation) + throw new Error('Initialization is incomplete'); + const sizes = this.calculateSizes(); this.canvas.resize(sizes.rightwidth, sizes.topheight - 70); @@ -311,11 +314,11 @@ export class App { const h = this.handle; const b = this.tabs.tabs.dom; if (h.nextSibling == b) { - a.parentNode.insertBefore(b, a); - a.parentNode.insertBefore(h, a); + a.parentNode!.insertBefore(b, a); + a.parentNode!.insertBefore(h, a); } else { - a.parentNode.insertBefore(b, a.nextSibling); - a.parentNode.insertBefore(h, a.nextSibling); + a.parentNode!.insertBefore(b, a.nextSibling); + a.parentNode!.insertBefore(h, a.nextSibling); } } @@ -323,7 +326,10 @@ export class App { * Event handler when change window size (internal use) * @function onresize */ - onresize(delta) { + onresize(delta: number) { + if (!this.canvas || !this.properties || !this.structureview || !this.mex || !this.notation) + throw new Error('Initialization is incomplete'); + if (this.handle.nextSibling == this.tabs.tabs.dom) { const top = this.canvas.dimension.y; const bottom = scil.Utils.parsePixel(this.sequence.style.height); @@ -354,7 +360,7 @@ export class App { * create monomer explorer (internal use) * @function createPalette */ - createPalette(div, width, height) { + createPalette(div: HTMLDivElement, width: number, height: number): void { const opt = scil.clone(this.options); opt.width = width; opt.height = height; @@ -365,7 +371,7 @@ export class App { * create drawing canvas (internal use) * @function createCanvas */ - createCanvas(div, width, height) { + createCanvas(div: HTMLDivElement, width: number, height: number): void { div.style.border = "solid 1px #eee"; const me = this; @@ -378,7 +384,7 @@ export class App { }; this.canvas = org.helm.webeditor.Interface.createCanvas(div, args); - this.canvas.helm.monomerexplorer = this.mex; + this.canvas.helm!.monomerexplorer = this.mex; this.mex.plugin = this.canvas.helm; // TODO: ? this.canvas._testdeactivation = function(e, ed) { diff --git a/HELM/source/helm/Interface.ts b/HELM/source/helm/Interface.ts index 37ac974..fe26781 100644 --- a/HELM/source/helm/Interface.ts +++ b/HELM/source/helm/Interface.ts @@ -272,7 +272,7 @@ export class Interface implements IOrgInterface { p1.offset(-fontsize * 1.2, -fontsize * 1.2); JSDraw2.Drawer.drawLabel(surface, p1, a.bio!.id, "#00FF00", fontsize, null, null, null, false); } - if (!scil.Utils.isNullOrEmpty(a.bio!.annotation!)) { + if (!scil.Utils.isNullOrEmpty(a.bio!.annotation)) { const p1 = p.clone(); const s = a.bio!.annotation; if (a.bio!.annotationshowright) { @@ -382,7 +382,7 @@ export class Interface implements IOrgInterface { if (items.length > 0) items.push("-"); if (biotype == org.helm.webeditor.HELM.BLOB) - items.push({caption: "Blob Type", callback: function(cmd: string, obj: Atom) { ed.helm.setHelmBlobType(obj, cmd); }, children: org.helm.webeditor.blobtypes}); + items.push({caption: "Blob Type", callback: function(cmd: string, obj: Atom) { ed.helm!.setHelmBlobType(obj, cmd); }, children: org.helm.webeditor.blobtypes}); else if (a.group == null) items.push({caption: "Create Group", key: "helm_create_group"}); items.push("-"); diff --git a/HELM/source/helm/MonomerExplorer.ts b/HELM/source/helm/MonomerExplorer.ts index f6e0ae6..d40662e 100644 --- a/HELM/source/helm/MonomerExplorer.ts +++ b/HELM/source/helm/MonomerExplorer.ts @@ -22,8 +22,6 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ -// @ts-nocheck - import type {DojoType} from '@datagrok-libraries/js-draw-lite/src/types/dojo'; import type {JSDraw2ModuleType, ScilModuleType} from '@datagrok-libraries/js-draw-lite/src/types'; @@ -32,9 +30,9 @@ import type {HelmType, HelmTypes, IOrgMonomer, IWebEditorMonomer} from '@datagro import type {StyleType} from '@datagrok-libraries/js-draw-lite/src/types/common'; import type {IDnD} from '@datagrok-libraries/js-draw-lite/src/types/scil'; import type {Editor} from '@datagrok-libraries/js-draw-lite/src/JSDraw.Editor'; +import type {Tabs} from '@datagrok-libraries/js-draw-lite/form/Tab'; declare const dojo: DojoType; -declare const scilligence: ScilModuleType; declare const scil: ScilModuleType; declare const org: OrgType; declare const JSDraw2: JSDraw2ModuleType; @@ -47,7 +45,7 @@ declare let JSDrawServices: any; export class MonomerExplorerInt { private readonly T: string; public plugin: any; // TODO: ? - private readonly options: any; + private readonly options: Partial; private height: number | null; private kStyle: any; private selected: { [type: string]: string }; @@ -63,7 +61,7 @@ export class MonomerExplorerInt { private rules_category!: HTMLSelectElement; private curtab: any; - private monomerstabs: any; + private monomerstabs?: Tabs; private rnatabs: any; private divRule?: HTMLDivElement; @@ -74,6 +72,8 @@ export class MonomerExplorerInt { private lastdiv?: HTMLDivElement; private pinmenu: any; + private readonly logger: Console = window.console; + /** * @constructor MonomerExplorer * @param {DOM} parent - The parent element @@ -85,7 +85,7 @@ export class MonomerExplorerInt { this.plugin = plugin; this.options = options == null ? {} : options; this.height = null; - const w = this.options.monomerwidth > 0 ? this.options.monomerwidth : 50; + const w = this.options.monomerwidth! > 0 ? this.options.monomerwidth : 50; this.kStyle = {borderRadius: '5px', border: 'solid 1px gray', backgroundRepeat: 'no-repeat', display: 'table', width: w, height: w, float: 'left', margin: 2}; if (this.options.mexuseshape) @@ -130,13 +130,20 @@ export class MonomerExplorerInt { }); } - const tabs: TabDescType[] = []; + // Monomers + let tabs: TabDescType[] = []; if (this.options.mexmonomerstab) tabs.push({caption: 'Monomers', tabkey: 'monomers'}); else this.addMonomerTabs(tabs); + + // Rules tabs.push({caption: 'Rules', tabkey: 'rule'}); + // Override tabs from options + if (this.options.overrideTabs) + tabs = this.options.overrideTabs(tabs); + const width = this.options.width != null ? this.options.width : 300; this.height = this.options.height != null ? this.options.height : 400; this.tabs = new scil.Tabs(scil.Utils.createElement(this.div, 'div', null, {padding: '5px'}), { @@ -219,7 +226,7 @@ export class MonomerExplorerInt { } else if (s.length >= 3 || org.helm.webeditor.MonomerExplorer.filtername) { const type = d.getAttribute('helm'); const set = type == org.helm.webeditor.MonomerExplorer.kNucleotide ? org.helm.webeditor.MonomerExplorer.nucleotides : org.helm.webeditor.Monomers.getMonomerSet(type); - const m = set[scil.helm.symbolCase(name)]; + const m = set![scil.helm.symbolCase(name)]; const monomer = m as IWebEditorMonomer; if (monomer != null && monomer.n != null) { if (scil.Utils.startswith(monomer.n.toLowerCase(), s)) @@ -250,9 +257,9 @@ export class MonomerExplorerInt { parent.insertBefore(d.div, parent.childNodes[i]); last = d.div; if (s != null) - (d.div.firstChild!.firstChild as HTMLElement).innerHTML = this.highlightString(d.id, s); + (d.div.firstChild!.firstChild as HTMLElement).innerHTML = this.highlightString(d.id!, s); else - (d.div.firstChild!.firstChild as HTMLElement).innerHTML = d.html != null ? d.html : d.id; + (d.div.firstChild!.firstChild as HTMLElement).innerHTML = d.html != null ? d.html : d.id!; d.div.style.display = 'table'; } @@ -376,6 +383,7 @@ export class MonomerExplorerInt { * @function onShowTab */ onShowTab(td: HTMLTableCellElement & any, forcerecreate?: boolean): void { + const logPrefix = `HWE: MonomerExplorer.onShowTab()`; if (td == null) return; @@ -384,6 +392,7 @@ export class MonomerExplorerInt { this.filterGroup(''); const key = td.getAttribute('key'); + this.logger.debug(`${logPrefix}, key = ${key}`); if (forcerecreate || key == 'favorite' && org.helm.webeditor.MonomerExplorer.favorites.changed) { td._childrencreated = false; if (key == 'favorite') @@ -396,72 +405,128 @@ export class MonomerExplorerInt { return; td._childrencreated = true; - const me = this; - const div = td.clientarea; + const div: HTMLDivElement = td.clientarea; scil.Utils.unselectable(div); scil.Utils.removeAll(div); - if (key == 'favorite') { - this.divFavorite = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `{this.getHeight(key)}px`, overflowY: 'scroll'}); - this.recreateFavorites(this.divFavorite); - } else if (key == 'rna') { - const d = scil.Utils.createElement(div, 'div'); - this.createMonomerGroup3(d, 'RNA', 0, false); - } else if (key == 'nucleotide') { - const dict = org.helm.webeditor.MonomerExplorer.loadNucleotides(); - const list = scil.Utils.getDictKeys(dict); - this.createMonomerGroup4(div, key, list); - } else if (key == 'aa') { - this.divAA = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `${this.getHeight(key)}px`, overflowY: 'scroll'}); - dojo.connect(this.divAA, 'onmousedown', function(e: MouseEvent) { - me.select(e); - }); - dojo.connect(this.divAA, 'ondblclick', function(e: MouseEvent) { - me.dblclick(e); - }); - this.createMonomerGroup4(this.divAA, org.helm.webeditor.HELM.AA, null, false, this.options.mexgroupanalogs != false); - } else if (key == 'chem') { - this.divChem = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `${this.getHeight(key)}px`, overflowY: 'scroll'}); - this.createMonomerGroup(this.divChem, org.helm.webeditor.HELM.CHEM); - } else if (key == 'base') { - this.createMonomerGroup4(div, org.helm.webeditor.HELM.BASE, null, null, this.options.mexgroupanalogs != false); - } else if (key == 'sugar') { - this.createMonomerGroup4(div, org.helm.webeditor.HELM.SUGAR, null); - } else if (key == 'linker') { - this.createMonomerGroup4(div, org.helm.webeditor.HELM.LINKER, null, true); - } else if (key == 'rule') { - const toolbar = scil.Utils.createElement(div, 'div', null, {background: '#ccc'}); - scil.Utils.createElement(toolbar, 'span', 'Category:'); - this.rules_category = scil.Utils.createElement(toolbar, 'select'); - scil.Utils.listOptions(this.rules_category, org.helm.webeditor.RuleSetApp.categories); - const me = this; - scil.connect(this.rules_category, 'onchange', function() { - org.helm.webeditor.RuleSet.filterRules(me.rules, me.filterInput.value, me.rules_category?.value); - }); + switch (key) { + case 'favorite': + this.onShowTabFavorite(div); + break; + case 'rna': + this.onShowTabRna(div); + break; + case 'nucleotide': + this.onShowTabNucleotide(div, key); + break; + case 'aa': + this.onShowTabAa(div, key); + break; + case 'chem': + this.onShowTabChem(div, key); + break; + case 'base': + this.onShowTabBase(div); + break; + case 'sugar': + this.onShowTabSugar(div); + break; + case 'linker': + this.onShowTabLinker(div); + break; + case 'rule': + this.onShowTabRule(div, key); + break; + case 'monomers': + this.onShowTabMonomers(div); + break; + default: + if (this.options.onShowTab) + this.options.onShowTab(this, div, key); + break; + } + } - this.divRule = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `${this.getHeight(key)}px`, overflowY: 'scroll'}); - this.listRules(); - } else if (key == 'monomers') { - const d = scil.Utils.createElement(div, 'div', null, {paddingTop: '5px'}); + private onShowTabFavorite(div: HTMLDivElement) { + this.divFavorite = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `{this.getHeight(key)}px`, overflowY: 'scroll'}); + this.recreateFavorites(this.divFavorite); + } - if (this.options.canvastoolbar == false) { - const b = scil.Utils.createElement(d, 'div', 'Mouse Pointer', {cursor: 'pointer', padding: '2px', border: 'solid 1px gray', margin: '5px'}); - scil.connect(b, 'onclick', function() { - me.plugin.jsd.doCmd('lasso'); - }); - } + private onShowTabRna(div: HTMLDivElement) { + const d = scil.Utils.createElement(div, 'div'); + this.createMonomerGroup3(d, 'RNA', 0, false); + } - const tabs: TabDescType[] = []; - this.addMonomerTabs(tabs); - this.monomerstabs = new scil.Tabs(d, { - onShowTab(td: HTMLTableCellElement) { - me.onShowTab(td); - }, - tabpadding: '5px 2px 1px 2px', - tabs: tabs, - marginBottom: 0, + private onShowTabNucleotide(div: HTMLDivElement, key: string) { + const dict = org.helm.webeditor.MonomerExplorer.loadNucleotides(); + const list = scil.Utils.getDictKeys(dict); + this.createMonomerGroup4(div, key as HweHelmType, list); + } + + private onShowTabAa(div: HTMLDivElement, key: string) { + const me = this; + this.divAA = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `${this.getHeight(key)}px`, overflowY: 'scroll'}); + dojo.connect(this.divAA, 'onmousedown', function(e: MouseEvent) { + me.select(e); + }); + dojo.connect(this.divAA, 'ondblclick', function(e: MouseEvent) { + me.dblclick(e); + }); + this.createMonomerGroup4(this.divAA, org.helm.webeditor.HELM.AA, null, false, this.options.mexgroupanalogs != false); + } + + private onShowTabChem(div: HTMLDivElement, key: string) { + this.divChem = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `${this.getHeight(key)}px`, overflowY: 'scroll'}); + this.createMonomerGroup(this.divChem, org.helm.webeditor.HELM.CHEM); + } + + private onShowTabBase(div: HTMLDivElement) { + this.createMonomerGroup4(div, org.helm.webeditor.HELM.BASE, null, null, this.options.mexgroupanalogs != false); + } + + private onShowTabSugar(div: HTMLDivElement) { + this.createMonomerGroup4(div, org.helm.webeditor.HELM.SUGAR, null); + } + + private onShowTabLinker(div: HTMLDivElement) { + this.createMonomerGroup4(div, org.helm.webeditor.HELM.LINKER, null, true); + } + + private onShowTabRule(div: HTMLDivElement, key: string) { + const toolbar = scil.Utils.createElement(div, 'div', null, {background: '#ccc'}); + scil.Utils.createElement(toolbar, 'span', 'Category:'); + this.rules_category = scil.Utils.createElement(toolbar, 'select'); + scil.Utils.listOptions(this.rules_category, org.helm.webeditor.RuleSetApp.categories); + const me = this; + scil.connect(this.rules_category, 'onchange', function() { + org.helm.webeditor.RuleSet.filterRules(me.rules, me.filterInput.value, me.rules_category?.value); + }); + + this.divRule = scil.Utils.createElement(div, 'div', null, {width: '100%', height: `${this.getHeight(key)}px`, overflowY: 'scroll'}); + this.listRules(); + } + + private onShowTabMonomers(div: HTMLDivElement) { + const me = this; + const d = scil.Utils.createElement(div, 'div', null, {paddingTop: '5px'}); + + if (this.options.canvastoolbar == false) { + const b = scil.Utils.createElement(d, 'div', 'Mouse Pointer', {cursor: 'pointer', padding: '2px', border: 'solid 1px gray', margin: '5px'}); + scil.connect(b, 'onclick', function() { + me.plugin.jsd.doCmd('lasso'); }); } + + const mTabs: TabDescType[] = []; + this.addMonomerTabs(mTabs); + this.monomerstabs = new scil.Tabs(d, { + onShowTab(td: HTMLTableCellElement) { + me.onShowTab(td); + }, + tabpadding: '5px 2px 1px 2px', + tabs: mTabs, + marginBottom: 0, + }); } listRules() { @@ -470,14 +535,14 @@ export class MonomerExplorerInt { me.plugin.applyRule(script); }, function(scripts: any[]) { me.plugin.applyRules(scripts); - }); + })!; } /** * Get monomers by natural analog (internal use) * @function getMonomerDictGroupByAnalog */ - getMonomerDictGroupByAnalog(type: string): { [k: string]: any[] } { + getMonomerDictGroupByAnalog(type: HelmType): { [k: string]: any[] } { const set = org.helm.webeditor.Monomers.getMonomerSet(type); //for (var k in set) // set[k].id = k; @@ -493,9 +558,9 @@ export class MonomerExplorerInt { const m: IWebEditorMonomer = set[k]; let na: string = m.na!; if (aa) { - if (m.at.R1 == null) + if (m.at!.R1 == null) na = 'N-Term'; - else if (m.at.R2 == null) + else if (m.at!.R2 == null) na = 'C-Term'; } if (scil.Utils.isNullOrEmpty(na)) @@ -515,13 +580,13 @@ export class MonomerExplorerInt { * Get monomer list of a monomer type (internal use) * @function getMonomerList */ - getMonomerList(list: any, type: string, addnull?: boolean | null): string[] { + getMonomerList(list: any, type: HelmType, addnull?: boolean | null): string[] { if (list != null) { list.sort(); return list; } - var set = org.helm.webeditor.Monomers.getMonomerSet(type); + const set = org.helm.webeditor.Monomers.getMonomerSet(type); //for (var k in set) // set[k].id = k; list = scil.Utils.getDictValues(set); @@ -539,7 +604,7 @@ export class MonomerExplorerInt { list.sort(org.helm.webeditor.MonomerExplorer.compareMonomers); for (let i = 0; i < list.length; ++i) - ret.push(list[i].id); + ret.push(list[i].id!); return ret; } @@ -664,7 +729,7 @@ export class MonomerExplorerInt { */ createMonomerGroup4(div: HTMLDivElement, type: HweHelmType, list: string[] | null, addnull?: boolean | null, groupbyanalog?: boolean | null): void { if (groupbyanalog) { - const dict: { [k: string]: any[] } = this.getMonomerDictGroupByAnalog(type); + const dict: { [k: string]: any[] } = this.getMonomerDictGroupByAnalog(type as HelmType); if (org.helm.webeditor.ambiguity) { if (type == org.helm.webeditor.HELM.AA) @@ -705,13 +770,13 @@ export class MonomerExplorerInt { } else { if (type == 'nucleotide' && !this.options.mexrnapinontab) { const me = this; - const d = this.createMonomerDiv(div, scil.Utils.imgTag('pin.png'), 'nucleotide', null, false); + const d = this.createMonomerDiv(div, scil.Utils.imgTag('pin.png'), 'nucleotide', undefined, false); d.setAttribute('title', 'Pin This Nucleotide'); scil.connect(d, 'onclick', function() { me.addNucleotide(); }); } - list = this.getMonomerList(list, type, addnull); + list = this.getMonomerList(list, type as HelmType, addnull); if (org.helm.webeditor.ambiguity) { if (type == org.helm.webeditor.HELM.SUGAR) list.splice(0, 0, '*'); @@ -751,7 +816,7 @@ export class MonomerExplorerInt { * Inner loop listing all monomer of a monomer type (internal use) * @function */ - _listMonomer2(div: HTMLDivElement, k: string, list: any[], type: string, width: number) { + _listMonomer2(div: HTMLDivElement, k: string, list: any[], type: HweHelmType, width: number) { if (list.length == 0) return; @@ -759,7 +824,8 @@ export class MonomerExplorerInt { const tr = scil.Utils.createElement(tbody, 'tr'); const left = scil.Utils.createElement(tr, 'td', null, {verticalAlign: 'top'}); const right = scil.Utils.createElement(tr, 'td', null, {verticalAlign: 'top'}); - scil.Utils.createElement(left, 'div', k, {width: `${width}px`, background: '#eee', border: 'solid 1px #aaa', textAlign: 'center'}); + const groupKeyDiv = scil.Utils.createElement(left, 'div', k, {width: `${width}px`, background: '#eee', border: 'solid 1px #aaa', textAlign: 'center'}); + groupKeyDiv.classList.add('hwe-group-key'); this._listMonomers(right, list, type); } @@ -767,7 +833,7 @@ export class MonomerExplorerInt { * Create favorite monomer group (internal use) * @function createMonomerGroupFav */ - createMonomerGroupFav(div: HTMLDivElement, caption: string, type: string) { + createMonomerGroupFav(div: HTMLDivElement, caption: string, type: HweHelmType): void { const list = org.helm.webeditor.MonomerExplorer.favorites.getList(type); if (list == null || list.length == 0) return; @@ -790,7 +856,7 @@ export class MonomerExplorerInt { * List a monomer group (internal use) * @function _listMonomers */ - _listMonomers(div: HTMLElement, list: any[], type: string, mexfavoritefirst?: boolean) { + _listMonomers(div: HTMLElement, list: any[], type: HweHelmType, mexfavoritefirst?: boolean) { div.className = 'filtergroup'; if (mexfavoritefirst) { @@ -815,7 +881,7 @@ export class MonomerExplorerInt { * @function */ recreateFavorites(d: HTMLDivElement) { - this.createMonomerGroupFav(d, 'Nucleotide', org.helm.webeditor.MonomerExplorer.kNucleotide); + this.createMonomerGroupFav(d, 'Nucleotide', org.helm.webeditor.MonomerExplorer.kNucleotide as HweHelmType); this.createMonomerGroupFav(d, 'Base', org.helm.webeditor.HELM.BASE); this.createMonomerGroupFav(d, 'Sugar', org.helm.webeditor.HELM.SUGAR); this.createMonomerGroupFav(d, 'Linker', org.helm.webeditor.HELM.LINKER); @@ -827,13 +893,14 @@ export class MonomerExplorerInt { * Create a monomer block (internal use) * @function createMonomerDiv */ - createMonomerDiv(parent: HTMLElement, name: string | null, type: string, style?: any, star?: any) { + createMonomerDiv( + parent: HTMLElement, name: string | null, type?: HweHelmType, + argStyle?: Partial, star: boolean = false + ): HTMLDivElement { const fav = org.helm.webeditor.MonomerExplorer.favorites.contains(name, type); - if (style == null) - style = scil.clone(this.kStyle); - else - style = scil.apply(scil.clone(this.kStyle), style); + const style = argStyle ? scil.apply(scil.clone(this.kStyle), argStyle) : + scil.clone(this.kStyle); if (this.options.mexusecolor != false) { let color; @@ -841,7 +908,7 @@ export class MonomerExplorerInt { if (type == 'nucleotide' && custom != null && custom[name!] != null) color = {backgroundcolor: '#afa'}; else - color = style.backgroundColor = org.helm.webeditor.Monomers.getColor2(type, name); + color = style.backgroundColor = org.helm.webeditor.Monomers.getColor2(type as HelmType, name!); style.backgroundColor = color == null ? null : color.backgroundcolor; } @@ -959,11 +1026,12 @@ export class MonomerExplorerInt { let src = this.getMonomerDiv(e); if (src != null && !this.dnd.isDragging()) { const type = src.getAttribute('helm')!; - const set = type == org.helm.webeditor.MonomerExplorer.kNucleotide ? org.helm.webeditor.MonomerExplorer.nucleotides : org.helm.webeditor.Monomers.getMonomerSet(type); + const set = type == org.helm.webeditor.MonomerExplorer.kNucleotide ? + org.helm.webeditor.MonomerExplorer.nucleotides : org.helm.webeditor.Monomers.getMonomerSet(type as HelmType); const s = scil.Utils.getInnerText(src); - let m = set[scil.helm.symbolCase(s)]; + let m = set![scil.helm.symbolCase(s)]; if (m == null) - m = set[s]; + m = set![s]; org.helm.webeditor.MolViewer.show(e, type as HelmType, m, s); } else { src = (e.srcElement || e.target) as HTMLDivElement; diff --git a/HELM/source/helm/Monomers.ts b/HELM/source/helm/Monomers.ts index 0f31d82..40db05c 100644 --- a/HELM/source/helm/Monomers.ts +++ b/HELM/source/helm/Monomers.ts @@ -22,14 +22,17 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ -// @ts-nocheck +// // @ts-nocheck import type { HelmType, IMonomerColors, IOrgMonomers, MonomerType, PolymerType, MonomerSetType, IWebEditorMonomer } from '@datagrok-libraries/js-draw-lite/src/types/org'; -import type {GetMonomerFunc, IOrgHelmMonomers, OrgType} from '../src/types/org-helm'; +import type { + HelmAtom, + GetMonomerFunc, IOrgHelmMonomers, IRule, OrgType, GetMonomerResType, +} from '../src/types/org-helm'; + import type {JSDraw2ModuleType, ScilModuleType} from '@datagrok-libraries/js-draw-lite/src/types'; -import type {Atom} from '@datagrok-libraries/js-draw-lite/src/Atom'; declare const scil: ScilModuleType; declare const JSDraw2: JSDraw2ModuleType; @@ -41,9 +44,9 @@ declare const org: OrgType; */ export class Monomers implements IOrgHelmMonomers { private smilesmonomerid: number = 0; - public readonly smilesmonomers: {} = {}; + public readonly smilesmonomers: { [smiles: string]: IWebEditorMonomer } = {}; public readonly aliasset: {} = {}; - public readonly defaultmonomers: { [type: string]: any } = { + public readonly defaultmonomers: { [helmType: string]: any } = { HELM_BASE: null, HELM_SUGAR: null, HELM_LINKER: null, HELM_AA: null, HELM_CHEM: null }; public readonly blobs: { [name: string]: IWebEditorMonomer } = { @@ -51,11 +54,11 @@ export class Monomers implements IOrgHelmMonomers { group: {n: 'Group', id: "Group", na: 'G', rs: 0, at: {}, m: ''} }; - public sugars: MonomerSetType; - public linkers: MonomerSetType; - public bases: MonomerSetType; - public aas: MonomerSetType; - public chems: MonomerSetType; + public sugars: MonomerSetType = {}; + public linkers: MonomerSetType = {}; + public bases: MonomerSetType = {}; + public aas: MonomerSetType = {}; + public chems: MonomerSetType = {}; public cleanupurl?: string; public onMonomerSmiles?: Function; @@ -80,7 +83,7 @@ export class Monomers implements IOrgHelmMonomers { * Get the default monomer of a given monomer type (internal use) * @function getDefaultMonomer */ - getDefaultMonomer(monomertype) { + getDefaultMonomer(monomertype: HelmType) { const r = this.defaultmonomers[monomertype]; if (r != null) return r; @@ -104,7 +107,7 @@ export class Monomers implements IOrgHelmMonomers { * Tool function (internal use) * @function _getFirstKey */ - _getFirstKey(set, key1?: string, key2?: string) { + _getFirstKey(set: MonomerSetType, key1?: string, key2?: string) { if (key1 != null && set[scil.helm.symbolCase(key1)] != null) return set[scil.helm.symbolCase(key1)].id; if (key2 != null && set[scil.helm.symbolCase(key2)] != null) @@ -119,7 +122,7 @@ export class Monomers implements IOrgHelmMonomers { * Save monomers as text database (internal use) * @function saveTextDB */ - saveTextDB(url) { + saveTextDB(url: string): string | undefined { const cols = ["id", "symbol", "name", "naturalanalog", "molfile", "smiles", "polymertype", "monomertype", "r1", "r2", "r3", "r4", "r5", "author", "createddate"]; let s = ""; const n = {n: 0}; @@ -141,7 +144,7 @@ export class Monomers implements IOrgHelmMonomers { * Save monomers into xml string (internal use) * @function saveMonomerDB */ - saveMonomerDB(url) { + saveMonomerDB(url: string): string | undefined { let s = "\n"; s += "\n"; @@ -173,7 +176,7 @@ export class Monomers implements IOrgHelmMonomers { * Save all monomers into a text file * @function saveMonomersAsText */ - saveMonomersAsText(set: {}, type: PolymerType, mt: MonomerType, cols, n) { + saveMonomersAsText(set: MonomerSetType, type: PolymerType, mt: MonomerType, cols: string[], n: { n: number }): string { let ret = ""; for (const id in set) { const s = this.writeOneAsText({id: ++n.n, symbol: id, monomertype: mt, polymertype: type, name: set[id].n, naturalanalog: set[id].na, m: set[id]}, cols); @@ -187,7 +190,7 @@ export class Monomers implements IOrgHelmMonomers { * Save all Monomers into xml * @function saveMonomers */ - saveMonomers(set, type, mt) { + saveMonomers(set: MonomerSetType, type: PolymerType, mt: MonomerType) { let s = ""; for (const id in set) s += this.writeOne({id: id, mt: mt, type: type, m: set[id]}); @@ -198,8 +201,8 @@ export class Monomers implements IOrgHelmMonomers { * Load monomer from a web service * @function loadFromUrl */ - loadFromUrl(url, callback) { - const fn = function(xml) { + loadFromUrl(url: string, callback: Function): void { + const fn = function(xml: string) { org.helm.webeditor.Monomers.loadFromXml(xml); if (callback != null) callback(); @@ -211,7 +214,7 @@ export class Monomers implements IOrgHelmMonomers { * Load monomer from xml string * @function loadFromXml */ - loadFromXml(s: string): boolean { + loadFromXml(s: string): boolean | undefined { const doc = scil.Utils.parseXml(s); if (doc == null) return false; @@ -222,7 +225,7 @@ export class Monomers implements IOrgHelmMonomers { * Load monomer from json array coming from database * @function loadDB */ - loadDB(list, makeMon, clearall?: boolean) { + loadDB(list: IRule[] | any, makeMon?: Function, clearall?: boolean): void { if (clearall != false) this.clear(); @@ -232,7 +235,7 @@ export class Monomers implements IOrgHelmMonomers { for (let i = 0; i < list.length; ++i) { const x = list[i]; - let m = null; + let m: IWebEditorMonomer | null = null; if (makeMon != null) { m = makeMon(x); } else { @@ -249,7 +252,7 @@ export class Monomers implements IOrgHelmMonomers { m.rs = rs; } - this.addOneMonomer(m); + this.addOneMonomer(m!); } } @@ -257,7 +260,7 @@ export class Monomers implements IOrgHelmMonomers { * Load monomer from XML * @function loadMonomers */ - loadMonomers(doc, callback?: Function): boolean { + loadMonomers(doc: HTMLElement, callback?: Function): boolean | undefined { const list = doc.getElementsByTagName("Monomer"); if (list == null || list.length == 0) return false; @@ -271,11 +274,11 @@ export class Monomers implements IOrgHelmMonomers { return true; } - const newmonomers = []; - const overlapped = []; + const newmonomers: IWebEditorMonomer[] = []; + const overlapped: IWebEditorMonomer[] = []; for (let i = 0; i < list.length; ++i) { const m = this.readOne(list[i]); - const old = this.getMonomer(this.helm2Type(m), m.id); + const old = this.getMonomer(this.helm2Type(m)!, m.id); if (old == null) newmonomers.push(m); else { @@ -301,7 +304,7 @@ export class Monomers implements IOrgHelmMonomers { * Rename a monomer (internal use) * @function renameNextMonomer */ - renameNextMonomer(newmonomers, overlapped, callback) { + renameNextMonomer(newmonomers: IWebEditorMonomer[], overlapped: IWebEditorMonomer[], callback: Function): void { if (overlapped.length == 0) { callback(); return; @@ -313,7 +316,8 @@ export class Monomers implements IOrgHelmMonomers { scil.Utils.prompt2({ caption: "Duplicate Monomer", message: "Monomer name, " + m.id + ", is used. Please enter a new name for it:", - callback: function(s) { + callback: function(s: string) { + // @ts-ignore if (me.getMonomer(m.type, s) == null) { m.oldname = m.id; m.id = s; @@ -325,7 +329,7 @@ export class Monomers implements IOrgHelmMonomers { }); } - getAliases(biotype) { + getAliases(biotype: HelmType): MonomerSetType | null { return null; } @@ -333,11 +337,12 @@ export class Monomers implements IOrgHelmMonomers { * Get the monomer set by its type (internal use) * @function getMonomerSet */ - getMonomerSet(a) { + getMonomerSet(a: HelmAtom | HelmType | null): MonomerSetType | null { if (a == null) return null; - if (a.T == "ATOM") - a = a.biotype(); + const atom = a as HelmAtom; + if (atom.T == "ATOM") + a = atom.biotype(); if (a == org.helm.webeditor.HELM.BASE) return org.helm.webeditor.Monomers.bases; else if (a == org.helm.webeditor.HELM.SUGAR) @@ -357,12 +362,12 @@ export class Monomers implements IOrgHelmMonomers { * Get all monomer colors (internal use) * @function getMonomerColors */ - getMonomerColors(a: Atom | HelmType): any { + getMonomerColors(a: HelmAtom | HelmType): any { if (a == null) return null; - const aa = a as Atom; - if (aa.T == "ATOM") - a = aa.biotype(); + const atom = a as HelmAtom; + if (atom.T == "ATOM") + a = atom.biotype()!; if (a == org.helm.webeditor.HELM.BASE) return org.helm.webeditor.MonomerColors.bases; else if (a == org.helm.webeditor.HELM.SUGAR) @@ -382,14 +387,14 @@ export class Monomers implements IOrgHelmMonomers { * Get monomer list of a type (internal use) * @function getMonomerList */ - getMonomerList(a) { + getMonomerList(a: HelmAtom | HelmType): string[] | null { const set = this.getMonomerSet(a); if (set == null) return null; - const ret = []; + const ret: string[] = []; for (const k in set) - ret.push(set[k].id); + ret.push(set[k].id!); return ret; } @@ -398,18 +403,18 @@ export class Monomers implements IOrgHelmMonomers { * Get a monomer by an object or its name (internal use) * @function getMonomer */ - getMonomer: GetMonomerFunc = (a: Atom | HelmType, name?: string): IWebEditorMonomer => { + getMonomer: GetMonomerFunc = (a: HelmAtom | HelmType, name?: string): GetMonomerResType => { if (a == null && name == null) return null; let s; - let biotype; + let biotype: HelmType; if (name == null) { - const aa = a as Atom; - biotype = aa.biotype(); - s = aa.elem; + const atom = a as HelmAtom; + biotype = atom.biotype()!; + s = atom.elem; } else { - biotype = a; + biotype = a as HelmType; s = org.helm.webeditor.IO.trimBracket(name); } @@ -431,20 +436,22 @@ export class Monomers implements IOrgHelmMonomers { if (m != null) return m; - set = this.getAliases(biotype); + set = this.getAliases(biotype!); if (set == null) return null; m = set[scil.helm.symbolCase(s)]; if (m != null) return m; + + return null; }; /** * Check if the monomer have a R group (internal use) * @function hasR */ - hasR(type, name, r) { + hasR(type: HelmType, name: string, r: string): boolean { const m = this.getMonomer(type, name); return m != null && m.at != null && m.at[r] != null; } @@ -453,16 +460,16 @@ export class Monomers implements IOrgHelmMonomers { * Get monomer color by a monomer object (internal use) * @function getColor */ - getColor(a: Atom | HelmType): IMonomerColors { - const aa = a as Atom; - let m: IWebEditorMonomer = this.getMonomer(aa, aa.elem); + getColor(a: HelmAtom | HelmType): IMonomerColors { + const aa = a as HelmAtom; + let m: IWebEditorMonomer = this.getMonomer(aa, aa.elem)!; if (m == null) m = {}; let mc = this.getMonomerColors(a); if (mc == null) mc = {}; - const color = mc[m.na]; + const color = mc[m.na!]; if (m.backgroundcolor == null && aa.elem == "?") m.backgroundcolor = org.helm.webeditor.MonomerColors.unknown; @@ -479,7 +486,7 @@ export class Monomers implements IOrgHelmMonomers { * Get monomer color by type by name (internal use) * @function getColor2 */ - getColor2(type, name) { + getColor2(type: HelmType, name: string) { let m = this.getMonomer(type, name); if (m == null) m = {}; @@ -487,7 +494,7 @@ export class Monomers implements IOrgHelmMonomers { let mc = this.getMonomerColors(type); if (mc == null) mc = {}; - const color = mc[m.na]; + const color = mc[m.na!]; return { linecolor: m.linecolor == null ? "#000" : m.linecolor, @@ -501,17 +508,17 @@ export class Monomers implements IOrgHelmMonomers { * Get the molfile of a monomer (internal use) * @function getMolfile */ - getMolfile(m) { + getMolfile(m: IWebEditorMonomer): string | null { if (m != null && m.m == null && m.mz != null) m.m = org.helm.webeditor.IO.uncompressGz(m.mz); - return m == null ? null : m.m; + return m == null || !m.m ? null : m.m; } /** * Convert XML type to HELM Editor type (internal use) * @function helm2Type */ - helm2Type(m: IWebEditorMonomer): HelmType { + helm2Type(m: IWebEditorMonomer): HelmType | null { if (m.type == "PEPTIDE") return org.helm.webeditor.HELM.AA; else if (m.type == "CHEM") @@ -529,7 +536,7 @@ export class Monomers implements IOrgHelmMonomers { return null; } - convertAtomMapping2Rs(smiles) { + convertAtomMapping2Rs(smiles: string | null): string | null { if (smiles == null) return null; @@ -539,8 +546,8 @@ export class Monomers implements IOrgHelmMonomers { return smiles; } - addSmilesMonomer(type, smiles) { - smiles = this.convertAtomMapping2Rs(smiles); + addSmilesMonomer(type: HelmType, smiles: string): IWebEditorMonomer | null { + smiles = this.convertAtomMapping2Rs(smiles)!; const ss = this.findSmilesRs(smiles); if (ss == null || ss.length == 0) return null; @@ -553,16 +560,16 @@ export class Monomers implements IOrgHelmMonomers { m.id = "#" + (++this.smilesmonomerid); m.name = "SMILES Monomer #" + this.smilesmonomerid; for (let i = 0; i < ss.length; ++i) - m.at[ss[i]] = "H"; + m.at![ss[i]] = "H"; m.rs = ss.length; - const set = this.getMonomerSet(type); + const set = this.getMonomerSet(type)!; set[scil.helm.symbolCase(m.id)] = m; if (this.cleanupurl != null) { if (this.onMonomerSmiles != null) { this.onMonomerSmiles(m, smiles); } else { - scil.Utils.ajax(this.cleanupurl, function(ret) { + scil.Utils.ajax(this.cleanupurl, function(ret: any) { if (ret != null && ret.output != null) m.m = ret.output; }, {input: smiles, inputformat: "smiles", outputformat: "mol"}); @@ -573,7 +580,7 @@ export class Monomers implements IOrgHelmMonomers { return m; } - chemAxon2JSDrawSmiles(smiles) { + chemAxon2JSDrawSmiles(smiles: string): string { return smiles; } @@ -608,7 +615,7 @@ export class Monomers implements IOrgHelmMonomers { * add one monomer to HELM Editor (internal use) * @function addOneMonomer */ - addOneMonomer(m) { + addOneMonomer(m: IWebEditorMonomer): boolean { const set = this.getMonomerSet(this.helm2Type(m)); if (set == null) return false; @@ -616,7 +623,7 @@ export class Monomers implements IOrgHelmMonomers { delete m.type; delete m.mt; - set[scil.helm.symbolCase(m.id)] = m; + set[scil.helm.symbolCase(m.id!)] = m; return true; } @@ -649,7 +656,7 @@ export class Monomers implements IOrgHelmMonomers { * Save one monomer into xml (internal use) * @function writeOne */ - writeOne(m) { + writeOne(m: any): string { let molfile = this.getMolfile(m.m); if (molfile != null) { const s = org.helm.webeditor.IO.compressGz(molfile); // compress molfile @@ -685,7 +692,7 @@ export class Monomers implements IOrgHelmMonomers { * Read one monomer from XML (internal use) * @function readOne */ - readOne(e): IWebEditorMonomer { + readOne(e: Element): IWebEditorMonomer { const s = this.readValue(e, "MonomerMolFile"); let m = null; let mz = null; @@ -699,11 +706,11 @@ export class Monomers implements IOrgHelmMonomers { const mon: IWebEditorMonomer = { type: this.readValue(e, "PolymerType") as PolymerType, mt: this.readValue(e, "MonomerType") as MonomerType, - id: this.readValue(e, "MonomerID"), - n: this.readValue(e, "MonomerName"), - na: this.readValue(e, "NaturalAnalog"), + id: this.readValue(e, "MonomerID") ?? undefined, + n: this.readValue(e, "MonomerName") ?? undefined, + na: this.readValue(e, "NaturalAnalog") ?? undefined, mz: mz, - m: m, + m: m ?? undefined, at: {} }; @@ -712,11 +719,11 @@ export class Monomers implements IOrgHelmMonomers { if (list != null) { for (let i = 0; i < list.length; ++i) { const a = list[i]; - const r = this.readValue(a, "AttachmentLabel"); + const r = this.readValue(a, "AttachmentLabel")!; const cap = this.readValue(a, "CapGroupName"); - if (mon.at[r] == null) + if (mon.at![r] == null) ++rs; - mon.at[r] = cap; + mon.at![r] = cap as any; } } @@ -728,7 +735,7 @@ export class Monomers implements IOrgHelmMonomers { * Tool function to ready XML text (internal use) * @function readValue */ - readValue(e, name) { + readValue(e: Element, name: string) { const list = e.getElementsByTagName(name); if (list == null || list.length == 0) return null; diff --git a/HELM/source/package-lock.json b/HELM/source/package-lock.json index 96412fc..f35b3f5 100644 --- a/HELM/source/package-lock.json +++ b/HELM/source/package-lock.json @@ -27,6 +27,26 @@ "webpack-cli": "^4.9.1" } }, + "../../../JSDraw.Lite/source/web": { + "name": "@datagrok-libraries/js-draw-lite", + "version": "0.0.4", + "devDependencies": { + "@types/node": "^18.11.18", + "@types/wu": "^2.1.44", + "@typescript-eslint/eslint-plugin": "latest", + "@typescript-eslint/parser": "latest", + "cross-env": "^7.0.3", + "css-loader": "^6.7.3", + "eslint": "latest", + "eslint-config-google": "latest", + "filemanager-webpack-plugin": "^8.0.0", + "source-map-loader": "^4.0.1", + "ts-loader": "^9.5.1", + "typescript": "^4.8.4", + "webpack": "^5.76.3", + "webpack-cli": "^4.9.1" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -40,9 +60,8 @@ } }, "node_modules/@datagrok-libraries/js-draw-lite": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@datagrok-libraries/js-draw-lite/-/js-draw-lite-0.0.4.tgz", - "integrity": "sha512-x9jvstN3Z+NoFrMf5oxzUOnYCkwjzx6lzF8oRAYXKWLNHky7Rsu2Rs8MpKYr91PFaf++QZw6rBoY7MH2h2ywSw==" + "resolved": "../../../JSDraw.Lite/source/web", + "link": true }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", diff --git a/HELM/source/src/types/org-helm.ts b/HELM/source/src/types/org-helm.ts index 03d7f04..67cf2fd 100644 --- a/HELM/source/src/types/org-helm.ts +++ b/HELM/source/src/types/org-helm.ts @@ -1,7 +1,12 @@ import type { - HelmType, IOrgMonomer, IOrgMonomers, IWebEditorMonomer, PolymerType, + HelmType, IOrgMonomer, IOrgMonomers, IWebEditorMonomer, MonomerSetType, PolymerType, } from '@datagrok-libraries/js-draw-lite/src/types/org'; +export type HelmAtom = Atom; +export type HelmBond = Bond; +export type HelmMol = Mol; +export type HelmString = string; + export type IMolFindResType = { b: Bond, a0: Atom, @@ -54,6 +59,7 @@ export interface IWebEditorSizes { // } export interface IAppOptions { + ambiguity: boolean; showabout: boolean; mexfontsize: string; mexrnapinontab: boolean; @@ -81,8 +87,21 @@ export interface IAppOptions { onCleanUpStructure: Function; calculatorurl: string; + + // MonomerExplorer + alwaysdrawnucleotide?: boolean; + monomerwidth?: number; + mexuseshape?: any; + useshape?: any; + mexfavoritetab?: boolean; + mexgroupanalogs?: boolean; + mexusecolor?: boolean; + overrideTabs: (tabs: TabDescType[]) => TabDescType[]; + onShowTab: (mex: MonomerExplorer, div: HTMLDivElement, key: string) => void; } +export interface IMonomerExplorerOptions extends IAppOptions {} + export type AppSizesType = { height: number, topheight: number, @@ -92,18 +111,27 @@ export type AppSizesType = { } export type GetMonomerResType = IWebEditorMonomer | null; -export type GetMonomerFunc = (a: Atom | HelmType, name?: string) => GetMonomerResType; +export type GetMonomerFunc = (a: HelmAtom | HelmType, name?: string) => GetMonomerResType; + +export type GetMonomerSetFunc = (a: HelmAtom | HelmType | null) => MonomerSetType | null; + +export type MonomersFuncs = { + getMonomer: GetMonomerFunc, + getMonomerSet: GetMonomerSetFunc, +} export interface IOrgHelmMonomers extends IOrgMonomers { - cleanupurl: string | null; + cleanupurl?: string; - bases: { [name: string]: string }; - linkers: { [name: string]: string }; - sugars: { [name: string]: string }; + sugars: MonomerSetType; + linkers: MonomerSetType; + bases: MonomerSetType; + aas: MonomerSetType; + chems: MonomerSetType; addOneMonomer(monomer: IWebEditorMonomer): void; getDefaultMonomer(type: HelmType): string; - getMolfile(monomer: IWebEditorMonomer): string; + getMolfile(monomer: IWebEditorMonomer): string | null | undefined; clear(): void; writeOne(m: IWebEditorMonomer): string; loadDB(list: any[], makeMon?: Function, clearall?: boolean): void; @@ -250,10 +278,11 @@ export interface IRule { } export interface IRuleSet { - rules: IRule[]; - loadDB(list: IRule[]): void; + loadDB(list: IRule[], makeMon?: Function, clearAll?: boolean): void; - [p: string]: any; + filterRules(...args: any[]): void; + listRules(...args: any[]): void; + applyRules(...args: any[]): void; } import type {IOrgWebEditor, IOrgInterface} from '@datagrok-libraries/js-draw-lite/src/types/org'; @@ -287,18 +316,6 @@ export interface IExplorerMonomer extends IOrgMonomer { "width": 290, "height": 852 } */ -export interface IMonomerExplorerOptions { - showabout: boolean; - mexfontsize: string; - mexrnapinontab: boolean; - topmargin: number; - mexmonomerstab: boolean; - sequenceviewonly: boolean; - mexfavoritefirst: boolean, - mexfilter: boolean, - width: number, - height: number, -} export type HweHelmType = HelmType | 'nucleotide'; @@ -325,7 +342,7 @@ export interface IOrgHelmWebEditor extends Omit, 'Interf Interface: Interface; /* single instance */ Monomers: Monomers; /* single instance */ - monomers: void; + monomers: Monomers; // TODO: Eliminate monomerTypeList(): { [type: string]: string };