in packages/ketcher-core/src/application/editor/actions/erase.ts [120:255]
export function fromFragmentDeletion(restruct, rawSelection) {
assert(!!rawSelection != null);
let action = new Action();
const atomsToRemove: Array<number> = [];
const frids: Array<number> = [];
const struct = restruct.molecule;
const selection = formatSelection(rawSelection);
selection.sgroups.forEach((sgroupId) => {
const sgroup = restruct.sgroups.get(sgroupId);
const sgroupAtoms = sgroup.item.atoms;
selection.atoms = selection.atoms.concat(sgroupAtoms);
restruct.molecule.bonds.forEach((bond, bondId) => {
if (
sgroupAtoms.indexOf(bond.begin) >= 0 &&
sgroupAtoms.indexOf(bond.end) >= 0
) {
selection.bonds.push(bondId);
}
});
});
selection.atoms = Array.from(new Set(selection.atoms));
selection.bonds = Array.from(new Set(selection.bonds));
selection.atoms.forEach((atomId) => {
const sgroup = struct.getGroupFromAtomId(atomId);
if (sgroup && sgroup.isSuperatomWithoutLabel) {
const attachmentPoints = sgroup.getAttachmentPoints();
attachmentPoints.forEach((attachmentPoint) => {
if (
attachmentPoint.atomId === atomId &&
isNumber(attachmentPoint.leaveAtomId) &&
!selection.atoms.includes(attachmentPoint.leaveAtomId)
) {
action.addOp(
new SGroupAtomRemove(sgroup.id, attachmentPoint.leaveAtomId),
);
action.addOp(new AtomDelete(attachmentPoint.leaveAtomId));
}
});
}
});
selection.atoms.forEach((aid) => {
restruct.molecule.atomGetNeighbors(aid).forEach((nei) => {
if (selection.bonds.indexOf(nei.bid) === -1) {
selection.bonds = selection.bonds.concat([nei.bid]);
}
});
});
const actionRemoveBonds = new Action();
selection.bonds.forEach((bid) => {
const frid = restruct.molecule.getBondFragment(bid);
if (frids.indexOf(frid) < 0) frids.push(frid);
actionRemoveBonds.mergeWith(
fromBondDeletion(restruct, bid, selection.atoms),
);
});
const removedRGroupAttachmentPoints: number[] = [];
selection.atoms.forEach((aid) => {
const frid3 = restruct.molecule.atoms.get(aid).fragment;
if (frids.indexOf(frid3) < 0) frids.push(frid3);
if (removeAtomFromSgroupIfNeeded(action, restruct, aid)) {
atomsToRemove.push(aid);
}
action.addOp(new AtomDelete(aid));
const attachmentPointsToDelete =
restruct.molecule.getRGroupAttachmentPointsByAtomId(aid);
attachmentPointsToDelete.forEach((id) => {
action.addOp(new RGroupAttachmentPointRemove(id));
removedRGroupAttachmentPoints.push(id);
});
});
removeSgroupIfNeeded(action, restruct, atomsToRemove);
selection.rxnArrows.forEach((id) => {
action.addOp(new RxnArrowDelete(id));
});
selection.rxnPluses.forEach((id) => {
action.addOp(new RxnPlusDelete(id));
});
selection.simpleObjects.forEach((id) => {
action.addOp(new SimpleObjectDelete(id));
});
selection.texts.forEach((id) => {
action.addOp(new TextDelete(id));
});
selection[IMAGE_KEY].forEach((id) => {
action.addOp(new ImageDelete(id));
});
selection[MULTITAIL_ARROW_KEY].forEach((id) => {
action.addOp(new MultitailArrowDelete(id));
});
const actionToDeleteRGroupAttachmentPoints = new Action();
selection.rgroupAttachmentPoints.forEach((id) => {
if (!removedRGroupAttachmentPoints.includes(id)) {
actionToDeleteRGroupAttachmentPoints.mergeWith(
fromRGroupAttachmentPointDeletion(restruct, id),
);
}
});
action = action.perform(restruct);
action
.mergeWith(actionRemoveBonds)
.mergeWith(actionToDeleteRGroupAttachmentPoints);
const rgForRemove: Array<number> = frids.map(
(frid) => RGroup.findRGroupByFragment(restruct.molecule.rgroups, frid)!,
);
while (frids.length > 0) {
action = fromFragmentSplit(restruct, frids.pop(), rgForRemove).mergeWith(
action,
);
}
return action;
}