diff --git a/packages/ketcher-core/src/application/editor/editor.types.ts b/packages/ketcher-core/src/application/editor/editor.types.ts index 4e0726c37e..ba0c47de02 100644 --- a/packages/ketcher-core/src/application/editor/editor.types.ts +++ b/packages/ketcher-core/src/application/editor/editor.types.ts @@ -41,6 +41,7 @@ export interface Editor { isDitrty: () => boolean setOrigin: () => void struct: (struct?: Struct) => Struct + structToAddFragment: (struct: Struct) => Struct subscribe: (eventName: string, handler: (data?: any) => any) => any unsubscribe: (eventName: string, subscriber: any) => void selection: (arg?: Selection | 'all' | null) => Selection | null diff --git a/packages/ketcher-core/src/application/ketcher.ts b/packages/ketcher-core/src/application/ketcher.ts index d7d4592cbc..2c3b2b560f 100644 --- a/packages/ketcher-core/src/application/ketcher.ts +++ b/packages/ketcher-core/src/application/ketcher.ts @@ -27,6 +27,19 @@ import { MolfileFormat } from 'domain/serializers' import { Struct } from 'domain/entities' import assert from 'assert' +async function prepareStructToRender( + structStr: string, + structService: StructService +): Promise { + const struct: Struct = await parseStruct(structStr, structService) + struct.initHalfBonds() + struct.initNeighbors() + struct.setImplicitHydrogen() + struct.markFragments() + + return struct +} + function parseStruct(structStr: string, structService: StructService) { const format = identifyStructFormat(structStr) const factory = new FormatterFactory(structService) @@ -150,18 +163,23 @@ export class Ketcher { async setMolecule(structStr: string): Promise { assert(typeof structStr === 'string') - const struct: Struct = await parseStruct(structStr, this.#structService) - struct.initHalfBonds() - struct.initNeighbors() - struct.setImplicitHydrogen() - struct.markFragments() + const struct: Struct = await prepareStructToRender( + structStr, + this.#structService + ) + this.#editor.struct(struct) } - async addFragment(fragment: string): Promise { - assert(typeof fragment === 'string') + async addFragment(structStr: string): Promise { + assert(typeof structStr === 'string') + + const struct: Struct = await prepareStructToRender( + structStr, + this.#structService + ) - throw Error('not implemented yet') + this.#editor.structToAddFragment(struct) } recognize(image: Blob, version?: string): Promise { diff --git a/packages/ketcher-react/src/script/editor/Editor.ts b/packages/ketcher-react/src/script/editor/Editor.ts index 093315d067..4c6b1b945b 100644 --- a/packages/ketcher-react/src/script/editor/Editor.ts +++ b/packages/ketcher-react/src/script/editor/Editor.ts @@ -99,6 +99,7 @@ interface Selection { rxnPluses?: Array rxnArrows?: Array } + class Editor implements KetcherEditor { #origin?: any render: Render @@ -146,6 +147,8 @@ class Editor implements KetcherEditor { this.historyPtr = 0 this.errorHandler = null this.highlights = new Highlighter(this) + this.renderAndRecoordinateStruct = + this.renderAndRecoordinateStruct.bind(this) this.event = { message: new Subscription(), @@ -209,6 +212,15 @@ class Editor implements KetcherEditor { this.struct(undefined) } + renderAndRecoordinateStruct(struct: Struct) { + const action = fromNewCanvas(this.render.ctab, struct) + this.update(action) + + const structCenter = getStructCenter(this.render.ctab) + recoordinate(this, structCenter) + return this.render.ctab.molecule + } + struct(value?: Struct): Struct { if (arguments.length === 0) { return this.render.ctab.molecule @@ -216,12 +228,15 @@ class Editor implements KetcherEditor { this.selection(null) const struct = value || new Struct() - const action = fromNewCanvas(this.render.ctab, struct) - this.update(action) - const structCenter = getStructCenter(this.render.ctab) - recoordinate(this, structCenter) - return this.render.ctab.molecule + return this.renderAndRecoordinateStruct(struct) + } + + // this is used by API addFragment method + structToAddFragment(value: Struct): Struct { + const superStruct = value.mergeInto(this.render.ctab.molecule) + + return this.renderAndRecoordinateStruct(superStruct) } options(value?: any) {