@datagrok/helm 2.3.3 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/helm",
3
3
  "friendlyName": "Helm",
4
- "version": "2.3.3",
4
+ "version": "2.4.1",
5
5
  "author": {
6
6
  "name": "Oleksandra Serhiienko",
7
7
  "email": "oserhiienko@datagrok.ai"
@@ -16,7 +16,7 @@
16
16
  "css/helm.css"
17
17
  ],
18
18
  "dependencies": {
19
- "@datagrok-libraries/bio": "^5.42.6",
19
+ "@datagrok-libraries/bio": "^5.42.9",
20
20
  "@datagrok-libraries/chem-meta": "^1.2.5",
21
21
  "@datagrok-libraries/utils": "^4.2.19",
22
22
  "cash-dom": "^8.1.1",
@@ -26,17 +26,18 @@
26
26
  "wu": "latest"
27
27
  },
28
28
  "devDependencies": {
29
- "@datagrok-libraries/helm-web-editor": "^1.1.6",
30
- "@datagrok-libraries/js-draw-lite": "^0.0.4",
31
- "@datagrok/bio": "^2.13.3",
29
+ "@datagrok-libraries/helm-web-editor": "^1.1.8",
30
+ "@datagrok-libraries/js-draw-lite": "^0.0.6",
31
+ "@datagrok/bio": "^2.14.1",
32
32
  "@datagrok/chem": "^1.9.2",
33
33
  "@types/node": "17.0.45",
34
34
  "@types/wu": "latest",
35
- "@typescript-eslint/eslint-plugin": "^5.11.0",
36
- "@typescript-eslint/parser": "^5.11.0",
35
+ "@typescript-eslint/eslint-plugin": "^7.16.0",
36
+ "@typescript-eslint/parser": "^7.16.0",
37
37
  "datagrok-tools": "latest",
38
38
  "eslint": "^8.18.0",
39
39
  "eslint-config-google": "^0.14.0",
40
+ "eslint-plugin-rxjs": "^5.0.3",
40
41
  "path": "^0.12.7",
41
42
  "source-map-loader": "^4.0.1",
42
43
  "ts-loader": "^9.2.6",
@@ -4,19 +4,19 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import wu from 'wu';
6
6
 
7
- import {HelmType, ISeqMonomer, Mol} from '@datagrok-libraries/bio/src/helm/types';
7
+ import {HelmMol, ISeqMonomer} from '@datagrok-libraries/bio/src/helm/types';
8
8
 
9
9
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
10
10
  import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
11
11
 
12
12
  import {findMonomers, parseHelm, removeGapsFromHelm} from './utils';
13
13
  import {HelmMonomerPlacer} from './helm-monomer-placer';
14
- import {getHoveredMonomerFallback, getHoveredMonomerFromEditorMol} from './utils/get-hovered';
15
- import {JSDraw2HelmModule} from './types';
14
+ import {getHoveredMonomerFallback, getHoveredMonomerFromEditorMol, getSeqMonomerFromHelmAtom} from './utils/get-hovered';
15
+ import {JSDraw2Module} from './types';
16
16
 
17
17
  import {_package} from './package';
18
18
 
19
- declare const JSDraw2: JSDraw2HelmModule;
19
+ declare const JSDraw2: JSDraw2Module;
20
20
 
21
21
  const enum tempTAGS {
22
22
  helmSumMaxLengthWords = 'helm-sum-maxLengthWords',
@@ -50,12 +50,13 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
50
50
  const argsY = e.offsetY - gcb.y;
51
51
 
52
52
  const monomerLib = _package.monomerLib;
53
- const editorMol: Mol<HelmType> | null = helmPlacer.getEditorMol(gridCell.tableRowIndex!);
53
+ const editorMol: HelmMol | null = helmPlacer.getEditorMol(gridCell.tableRowIndex!);
54
54
  let seqMonomer: ISeqMonomer | null;
55
55
  let missedMonomers: Set<string> = new Set<string>(); // of .size = 0
56
- if (editorMol)
57
- seqMonomer = getHoveredMonomerFromEditorMol(argsX, argsY, editorMol, gridCell.bounds.height);
58
- else {
56
+ if (editorMol) {
57
+ const hoveredAtom = getHoveredMonomerFromEditorMol(argsX, argsY, editorMol, gridCell.bounds.height);
58
+ seqMonomer = hoveredAtom ? getSeqMonomerFromHelmAtom(hoveredAtom) : null;
59
+ } else {
59
60
  const seq: string = !gridCell.cell.value ? '' : removeGapsFromHelm(gridCell.cell.value as string);
60
61
  const monomerList = parseHelm(seq);
61
62
  missedMonomers = findMonomers(monomerList, monomerLib);
@@ -3,23 +3,26 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {
6
- App, Atom, HelmType, GetMonomerFunc, GetMonomerResType, HelmString, HelmMol
6
+ App, Atom, HelmType, GetMonomerFunc, GetMonomerResType, HelmString, HelmMol,
7
+ MonomerExplorer, TabDescType, MonomersFuncs, MonomerSetType, HelmAtom, ISeqMonomer, PolymerType, MonomerType, type DojoType
7
8
  } from '@datagrok-libraries/bio/src/helm/types';
8
-
9
+ import {HelmTypes, MonomerTypes, PolymerTypes} from '@datagrok-libraries/bio/src/helm/consts';
9
10
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
10
11
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
11
- import {IHelmHelper, IInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
12
+ import {HelmInputBase, IHelmHelper, IHelmInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
12
13
  import {IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
13
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
14
+ import {IMonomerLib, IMonomerLinkData, IMonomerSetPlaceholder} from '@datagrok-libraries/bio/src/types/index';
15
+ import {HelmTabKeys, IHelmDrawOptions} from '@datagrok-libraries/helm-web-editor/src/types/org-helm';
14
16
 
15
17
  import {HelmWebEditor} from './helm-web-editor';
16
18
  import {OrgHelmModule, ScilModule} from './types';
17
19
  import {getWebEditorMonomer} from './utils/get-monomer';
18
20
  import {HelmInput} from './widgets/helm-input';
21
+ import {getHoveredMonomerFromEditorMol} from './utils/get-hovered';
19
22
 
20
23
  import {_package} from './package';
21
24
 
22
-
25
+ declare const dojo: DojoType;
23
26
  declare const scil: ScilModule;
24
27
  declare const org: OrgHelmModule;
25
28
 
@@ -34,9 +37,9 @@ export class HelmHelper implements IHelmHelper {
34
37
  throw new Error(`HelmHelper must be a single.`);
35
38
  }
36
39
 
37
- createHelmInput(name?: string, options?: IInputInitOptions<HelmMol>): DG.InputBase<HelmMol> {
40
+ createHelmInput(name?: string, options?: IHelmInputInitOptions): HelmInputBase {
38
41
  try {
39
- const monomerLib: IMonomerLib = _package.libHelper.getBioLib();
42
+ const monomerLib: IMonomerLib = _package.libHelper!.getMonomerLib();
40
43
  return HelmInput.create(this, monomerLib, name, options);
41
44
  } catch (err: any) {
42
45
  const [errMsg, errStack] = errInfo(err);
@@ -45,8 +48,8 @@ export class HelmHelper implements IHelmHelper {
45
48
  }
46
49
  }
47
50
 
48
- createHelmWebEditor(host?: HTMLDivElement): IHelmWebEditor {
49
- return new HelmWebEditor(host);
51
+ createHelmWebEditor(host?: HTMLDivElement, drawOptions?: Partial<IHelmDrawOptions>): IHelmWebEditor {
52
+ return new HelmWebEditor(host, drawOptions);
50
53
  }
51
54
 
52
55
  createWebEditorApp(host: HTMLDivElement, helm: string): App {
@@ -59,7 +62,36 @@ export class HelmHelper implements IHelmHelper {
59
62
  mexmonomerstab: true,
60
63
  sequenceviewonly: false,
61
64
  mexfavoritefirst: true,
62
- mexfilter: true
65
+ mexfilter: true,
66
+ // currentTabKey: HelmTabKeys.Helm,
67
+ overrideTabs: (tabs: Partial<TabDescType>[]): Partial<TabDescType>[] => {
68
+ const res: Partial<TabDescType>[] = [...tabs,
69
+ {caption: 'Placeholders', tabkey: 'placeholders'},
70
+ ];
71
+ return res;
72
+ },
73
+ onShowTab: (mex: MonomerExplorer, div: HTMLDivElement, key: string): void => {
74
+ switch (key) {
75
+ case 'placeholders': {
76
+ this.onShowTabPlaceholders(mex, div);
77
+ break;
78
+ }
79
+ case 'placeholders-meta': {
80
+ this.onShowTabPlaceholdersMeta(mex, div);
81
+ break;
82
+ }
83
+ case 'placeholders-sets': {
84
+ this.onShowTabPlaceholdersSets(mex, div);
85
+ break;
86
+ }
87
+ }
88
+ dojo.connect(div, 'onmousedown', function(e: MouseEvent) {
89
+ mex.select(e);
90
+ });
91
+ dojo.connect(div, 'ondblclick', function(e: MouseEvent) {
92
+ mex.dblclick(e);
93
+ });
94
+ }
63
95
  });
64
96
  const sizes = webEditorApp.calculateSizes();
65
97
  webEditorApp.canvas!.resize(sizes.rightwidth - 100, sizes.topheight - 210);
@@ -70,55 +102,215 @@ export class HelmHelper implements IHelmHelper {
70
102
  scil.apply(webEditorApp.properties!.parent.style, s);
71
103
  webEditorApp.structureview!.resize(sizes.rightwidth, sizes.bottomheight + webEditorApp.toolbarheight);
72
104
  webEditorApp.mex!.resize(sizes.topheight - 80);
73
- setTimeout(() => {
74
- webEditorApp.canvas!.helm!.setSequence(helm, 'HELM');
75
- }, 200);
105
+ webEditorApp.canvas?.setHelm(helm);
76
106
  return webEditorApp;
77
107
  }
78
108
 
109
+ // -- MonomerExplorer.onShowTab --
110
+
111
+ public onShowTabPlaceholders(mex: MonomerExplorer, div: HTMLDivElement): void {
112
+ const d = scil.Utils.createElement(div, 'div', null, {paddingTop: '5px'});
113
+
114
+ /* eslint-disable max-len*/
115
+ // if (this.options.canvastoolbar == false) {
116
+ // const b = scil.Utils.createElement(d, 'div', '<img src=\'' + scil.Utils.imgSrc('helm/arrow.png') + '\' style=\'vertical-align:middle\'>Mouse Pointer', {cursor: 'pointer', padding: '2px', border: 'solid 1px gray', margin: '5px'});
117
+ // scil.connect(b, 'onclick', function() {
118
+ // mex.plugin.jsd.doCmd('lasso');
119
+ // });
120
+ // }
121
+ /* eslint-enable max-len*/
122
+
123
+ const phTabs: Partial<TabDescType>[] = [];
124
+ phTabs.push({caption: 'Meta', tabkey: 'placeholders-meta'});
125
+ phTabs.push({caption: 'Sets', tabkey: 'placeholders-sets'});
126
+ const placeholdersTabs = new scil.Tabs(d, {
127
+ onShowTab(td: HTMLTableCellElement) {
128
+ mex.onShowTab(td);
129
+ },
130
+ tabpadding: '5px 2px 1px 2px',
131
+ tabs: phTabs,
132
+ marginBottom: `0`,
133
+ });
134
+ }
135
+
136
+ public onShowTabPlaceholdersMeta(mex: MonomerExplorer, div: HTMLDivElement): void {
137
+
138
+ }
139
+
140
+ public onShowTabPlaceholdersSets(mex: MonomerExplorer, div: HTMLDivElement): void {
141
+ const monomerSets = _package.libHelper!.getMonomerSets();
142
+
143
+ const phSet: { [polymerType: string]: { [helmType: string]: IMonomerSetPlaceholder[] } } = {};
144
+ for (const ph of monomerSets.placeholders) {
145
+ let ofPolymerTypeSet = phSet[ph.polymerType];
146
+ if (!ofPolymerTypeSet) ofPolymerTypeSet = phSet[ph.polymerType] = {};
147
+
148
+ const phHelmType = this.toHelmType(ph.polymerType, ph.monomerType);
149
+ let phList = ofPolymerTypeSet[phHelmType];
150
+ if (!phList) phList = ofPolymerTypeSet[phHelmType] = [];
151
+ phList.push(ph);
152
+ }
153
+
154
+ const fillPlaceholders = (
155
+ parentDiv: HTMLDivElement, phList: IMonomerSetPlaceholder[], helmType: HelmType
156
+ ): void => {
157
+ for (const ph of phList) {
158
+ const phDiv = mex.createMonomerDiv(parentDiv, ph.symbol, helmType);
159
+ ui.tooltip.bind(phDiv, () => {
160
+ const phTooltipDiv = ui.div([
161
+ ui.table(ph.monomerLinks, (ml: IMonomerLinkData, idx: number) => {
162
+ return [ml.symbol, ml.source];
163
+ }, ['Symbol', 'Library source'])
164
+ ]);
165
+ return phTooltipDiv;
166
+ });
167
+ }
168
+ };
169
+
170
+ const polymerTypes: [string, PolymerType][] = [
171
+ ['Chem', PolymerTypes.CHEM],
172
+ ['Peptide', PolymerTypes.PEPTIDE],
173
+ ['RNA', PolymerTypes.RNA],
174
+ ['Blob', PolymerTypes.BLOB],
175
+ ['G', PolymerTypes.G],
176
+ ];
177
+ const polymerTypeAcc = ui.accordion();
178
+ for (const [name, polymerType] of polymerTypes) {
179
+ if (polymerType in phSet) {
180
+ polymerTypeAcc.addPane(name, () => {
181
+ const polymerTypeDiv = ui.div();
182
+ const ofPolymerTypeSet = phSet[polymerType];
183
+ if (Object.keys(ofPolymerTypeSet).length == 1) {
184
+ const [helmType, phList] = Object.entries(ofPolymerTypeSet)[0];
185
+ fillPlaceholders(polymerTypeDiv, phList, helmType as HelmType);
186
+ } else {
187
+ const helmTypeAcc = ui.accordion();
188
+ for (const [helmTypeName, helmType] of Object.entries(HelmTypes)) {
189
+ if (helmType in ofPolymerTypeSet) {
190
+ helmTypeAcc.addPane(helmTypeName, () => {
191
+ const helmTypeDiv = ui.div();
192
+
193
+ const phList = ofPolymerTypeSet[helmType];
194
+ fillPlaceholders(helmTypeDiv, phList, helmType as HelmType);
195
+
196
+ return helmTypeDiv;
197
+ });
198
+ }
199
+ }
200
+ polymerTypeDiv.appendChild(helmTypeAcc.root);
201
+ }
202
+ return polymerTypeDiv;
203
+ }, true, undefined, false);
204
+ }
205
+ }
206
+ div.appendChild(polymerTypeAcc.root);
207
+ }
208
+
79
209
  // -- GetMonomer --
80
210
 
81
- public originalGetMonomer: GetMonomerFunc | null = null;
211
+ public originalMonomersFuncs: MonomersFuncs | null = null;
82
212
 
83
- public revertOriginalGetMonomer(): GetMonomerFunc {
213
+ public revertOriginalMonomersFuncs(): MonomersFuncs {
84
214
  const logPrefix = `Helm: revertOriginalGetMonomer()`;
85
- if (this.originalGetMonomer === null)
215
+ if (this.originalMonomersFuncs === null)
86
216
  throw new Error('Unable to revert original getMonomer');
87
217
 
88
218
  const monomers = org.helm.webeditor.Monomers;
89
- const overriddenGetMonomer = monomers.getMonomer = this.originalGetMonomer;
90
- this.originalGetMonomer = null;
91
- return overriddenGetMonomer;
219
+ const overriddenMonomersFuncs: MonomersFuncs = {
220
+ getMonomer: monomers.getMonomer,
221
+ getMonomerSet: monomers.getMonomerSet,
222
+ };
223
+
224
+ monomers.getMonomer = this.originalMonomersFuncs.getMonomer;
225
+ monomers.getMonomerSet = this.originalMonomersFuncs.getMonomerSet;
226
+ this.originalMonomersFuncs = null;
227
+
228
+ return overriddenMonomersFuncs;
92
229
  }
93
230
 
94
- public overrideGetMonomer(getMonomer: GetMonomerFunc): GetMonomerFunc {
95
- const logPrefix = `Helm: overrideGetMonomer()`;
231
+ public overrideMonomersFuncs(monomersFuncs: MonomersFuncs): MonomersFuncs {
232
+ const logPrefix = `Helm: HelmHelper.overrideGetMonomer()`;
96
233
 
97
- if (this.originalGetMonomer != null)
98
- throw new Error('');
234
+ if (this.originalMonomersFuncs != null)
235
+ throw new Error(`${logPrefix}, originalGetMonomer is overridden already`);
99
236
 
100
237
  const monomers = org.helm.webeditor.Monomers;
101
- this.originalGetMonomer = monomers.getMonomer.bind(monomers);
102
- monomers.getMonomer = getMonomer;
103
- return this.originalGetMonomer!;
238
+ this.originalMonomersFuncs = {
239
+ getMonomer: monomers.getMonomer.bind(monomers),
240
+ getMonomerSet: monomers.getMonomerSet.bind(monomers),
241
+ };
242
+ monomers.getMonomer = monomersFuncs.getMonomer;
243
+ monomers.getMonomerSet = monomersFuncs.getMonomerSet;
244
+ return this.originalMonomersFuncs!;
104
245
  }
105
246
 
106
- public buildGetMonomerFromLib(monomerLib: IMonomerLib): GetMonomerFunc {
247
+ public buildMonomersFuncsFromLib(monomerLib: IMonomerLib): MonomersFuncs {
107
248
  const logPrefix = `Helm: HelmHelper.buildGetMonomerFromLib()`;
108
- return (a: Atom<HelmType> | HelmType, name?: string): GetMonomerResType => {
109
- const logPrefixInt = `${logPrefix}, org.helm.webeditor.Monomers.getMonomer()`;
110
- try {
111
- // logger.debug(`${logPrefixInt}, a: ${JSON.stringify(a, helmJsonReplacer)}, name: '${name}'`);
112
-
113
- // Creates monomers in lib
114
- const dgWem = getWebEditorMonomer(monomerLib, a, name);
115
-
116
- return dgWem; //dgWem;
117
- } catch (err) {
118
- const [errMsg, errStack] = errInfo(err);
119
- this.logger.error(`${logPrefixInt}, Error: ${errMsg}`, undefined, errStack);
120
- throw err;
249
+
250
+ return {
251
+ getMonomer: (a: HelmAtom | HelmType, name?: string): GetMonomerResType => {
252
+ const logPrefixInt = `${logPrefix}, org.helm.webeditor.Monomers.getMonomer()`;
253
+ try {
254
+ // logger.debug(`${logPrefixInt}, a: ${JSON.stringify(a, helmJsonReplacer)}, name: '${name}'`);
255
+
256
+ // Creates monomers in lib
257
+ const dgWem = getWebEditorMonomer(monomerLib, a, name);
258
+
259
+ return dgWem; //dgWem;
260
+ } catch (err) {
261
+ const [errMsg, errStack] = errInfo(err);
262
+ this.logger.error(`${logPrefixInt}, Error: ${errMsg}`, undefined, errStack);
263
+ throw err;
264
+ }
265
+ },
266
+ getMonomerSet: (a: HelmAtom | HelmType | null): MonomerSetType | null => {
267
+ // if (a == null)
268
+ // return null;
269
+ // const atom = a as HelmAtom;
270
+ // if (atom.T === 'ATOM')
271
+ // a = atom.biotype();
272
+ // return monomerLib.getMonomerSet(a as HelmType);
273
+ return this.originalMonomersFuncs!.getMonomerSet(a);
121
274
  }
122
275
  };
123
276
  }
277
+
278
+ // helm2type(seqM: ISeqMonomer): HelmType {
279
+ // if (seqM.polymerType == "PEPTIDE")
280
+ // return org.helm.webeditor.HELM.AA;
281
+ // else if (seqM.polymerType == "CHEM")
282
+ // return org.helm.webeditor.HELM.CHEM;
283
+ // else if (seqM.polymerType == "RNA") {
284
+ // if (seqM.mt == "Branch")
285
+ // return org.helm.webeditor.HELM.BASE;
286
+ // if (seqM.mt == "Backbone") {
287
+ // if (seqM.na == "P" || seqM.na == "p")
288
+ // return org.helm.webeditor.HELM.LINKER;
289
+ // else
290
+ // return org.helm.webeditor.HELM.SUGAR;
291
+ // }
292
+ // }
293
+ // throw new Error(`Not supported seq monomer ${JSON.stringify(seqM)}.`);
294
+ // }
295
+ private toHelmType(polymerType: PolymerType, monomerType: MonomerType, naturalAnalog?: string) {
296
+ if (polymerType == PolymerTypes.PEPTIDE)
297
+ return org.helm.webeditor.HELM.AA;
298
+ else if (polymerType == PolymerTypes.CHEM)
299
+ return org.helm.webeditor.HELM.CHEM;
300
+ else if (polymerType == PolymerTypes.RNA) {
301
+ if (monomerType == MonomerTypes.BRANCH)
302
+ return org.helm.webeditor.HELM.BASE;
303
+ if (monomerType == MonomerTypes.BACKBONE) {
304
+ if (naturalAnalog == 'P' || naturalAnalog == 'p')
305
+ return org.helm.webeditor.HELM.LINKER;
306
+ else
307
+ return org.helm.webeditor.HELM.SUGAR;
308
+ }
309
+ }
310
+ throw new Error(`Not supported monomer polymerType: '${polymerType}', monomerType: '${monomerType}'.`);
311
+ }
312
+
313
+ public getHoveredAtom(x: number, y: number, mol: HelmMol, height: number): HelmAtom | null {
314
+ return getHoveredMonomerFromEditorMol(x, y, mol, height);
315
+ }
124
316
  }
@@ -73,7 +73,7 @@ export class HelmMonomerPlacer extends CellRendererBackBase<string> {
73
73
  // -- Handle events --
74
74
 
75
75
  private monomerLibOnChanged(_value: any): void {
76
- this.reset();
76
+ this.dirty = true;
77
77
  this.invalidateGrid();
78
78
  }
79
79
 
@@ -6,19 +6,19 @@ import {Unsubscribable} from 'rxjs';
6
6
 
7
7
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
8
8
  import {
9
- App, Editor, HelmType, IHelmWebEditor
9
+ App, Editor, HelmType, IHelmWebEditor, HelmEditor, IHelmDrawOptions
10
10
  } from '@datagrok-libraries/bio/src/helm/types';
11
11
 
12
- import {JSDraw2HelmModule, OrgHelmModule, ScilModule} from './types';
12
+ import {JSDraw2Module, OrgHelmModule, ScilModule} from './types';
13
13
 
14
14
  import {_package} from './package';
15
15
 
16
16
  declare const scil: ScilModule;
17
- declare const JSDraw2: JSDraw2HelmModule;
17
+ declare const JSDraw2: JSDraw2Module;
18
18
  declare const org: OrgHelmModule;
19
19
 
20
20
  export class HelmWebEditor implements IHelmWebEditor {
21
- editor: Editor<HelmType>;
21
+ editor: HelmEditor;
22
22
  host: HTMLDivElement;
23
23
 
24
24
  w = 200;
@@ -27,10 +27,19 @@ export class HelmWebEditor implements IHelmWebEditor {
27
27
 
28
28
  constructor(
29
29
  host?: HTMLDivElement,
30
+ drawOptions?: Partial<IHelmDrawOptions>,
30
31
  private logger: ILogger = _package.logger
31
32
  ) {
32
33
  this.host = host ?? ui.div([], {style: {width: `${this.w}px`, height: `${this.h}px`}});
33
- this.editor = new JSDraw2.Editor(this.host, {width: this.w, height: this.h, viewonly: true});
34
+
35
+ const styleBackup = {width: this.host.style.width, height: this.host.style.height, overflow: this.host.style.overflow};
36
+ this.editor = new JSDraw2.Editor(this.host, {
37
+ width: this.w, height: this.h, viewonly: true,
38
+ drawOptions: drawOptions
39
+ });
40
+ this.host.style.width = styleBackup.width;
41
+ this.host.style.height = styleBackup.height;
42
+ this.host.style.overflow = styleBackup.overflow;
34
43
 
35
44
  this.subs = [];
36
45
  this.subs.push(ui.onSizeChanged(this.host).subscribe(this.hostOnSizeChanged.bind(this)));
@@ -40,38 +49,19 @@ export class HelmWebEditor implements IHelmWebEditor {
40
49
  return `Helm: HelmWebEditor<#>`;
41
50
  }
42
51
 
43
- private hostOnSizeChanged(_: any): void {
44
- const logPrefix = `${this.toLog()}.hostOnSizeChanged()`;
45
- this.logger.debug(`${logPrefix}`);
46
- this.editor.setSize(this.host.clientWidth, this.host.clientHeight);
52
+ private lastSize: { width: number, height: number } = {width: -1, height: -1};
53
+
54
+ private hostOnSizeChanged(value: any): void {
55
+ const size = {width: value.target.clientWidth, height: value.target.clientHeight};
56
+ if (this.lastSize.width != size.width || this.lastSize.height != size.height) {
57
+ const logPrefix = `${this.toLog()}.hostOnSizeChanged()`;
58
+ this.logger.debug(`${logPrefix}`);
59
+ this.editor.setSize(this.host.clientWidth, this.host.clientHeight);
60
+ }
61
+ this.lastSize = size;
47
62
  }
48
63
 
49
64
  resizeEditor(w: number, h: number) {
50
65
  this.editor.setSize(w, h);
51
66
  }
52
67
  }
53
-
54
- export function buildWebEditorApp(view: HTMLDivElement): App {
55
- org.helm.webeditor.MolViewer.molscale = 0.8;
56
- const app = new org.helm.webeditor.App(view, {
57
- showabout: false,
58
- mexfontsize: '90%',
59
- mexrnapinontab: true,
60
- topmargin: 20,
61
- mexmonomerstab: true,
62
- sequenceviewonly: false,
63
- mexfavoritefirst: true,
64
- mexfilter: true
65
- });
66
- const sizes = app.calculateSizes();
67
- app.canvas!.resize(sizes.rightwidth - 100, sizes.topheight - 210);
68
- let s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
69
- scil.apply(app.sequence.style, s);
70
- scil.apply(app.notation!.style, s);
71
- s = {width: sizes.rightwidth + 'px', height: (sizes.bottomheight + app.toolbarheight) + 'px'};
72
- scil.apply(app.properties!.parent.style, s);
73
- app.structureview!.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
74
- app.mex!.resize(sizes.topheight - 80);
75
-
76
- return app;
77
- }