mirror of
https://github.com/3dmol/3Dmol.js.git
synced 2026-06-04 08:39:49 +09:00
fix: prevent crash when frames lack 3DMOL_STYLE blocks
This commit is contained in:
@@ -1998,7 +1998,7 @@ export class GLModel {
|
|||||||
}
|
}
|
||||||
model.molObj = null;
|
model.molObj = null;
|
||||||
if (model.modelDatas && framenum < model.modelDatas.length) {
|
if (model.modelDatas && framenum < model.modelDatas.length) {
|
||||||
model.modelData = model.modelDatas[framenum];
|
model.modelData = model.modelDatas[framenum] || {};
|
||||||
if (model.unitCellObjects && viewer) {
|
if (model.unitCellObjects && viewer) {
|
||||||
viewer.removeUnitCell(model);
|
viewer.removeUnitCell(model);
|
||||||
viewer.addUnitCell(model);
|
viewer.addUnitCell(model);
|
||||||
@@ -2127,7 +2127,7 @@ export class GLModel {
|
|||||||
var mData = parsedAtoms.modelData;
|
var mData = parsedAtoms.modelData;
|
||||||
if (mData) {
|
if (mData) {
|
||||||
if (Array.isArray(mData)) {
|
if (Array.isArray(mData)) {
|
||||||
this.modelData = mData[0];
|
this.modelData = mData[0] || {};
|
||||||
this.modelDatas = mData;
|
this.modelDatas = mData;
|
||||||
} else {
|
} else {
|
||||||
this.modelData = mData;
|
this.modelData = mData;
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ const apply3DmolStyle = function (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const frameAtoms = atoms[atoms.length - 1];
|
const frameIdx = atoms.length - 1;
|
||||||
|
const frameAtoms = atoms[frameIdx];
|
||||||
|
|
||||||
if (styleObj.bonds && typeof styleObj.bonds === "object") {
|
if (styleObj.bonds && typeof styleObj.bonds === "object") {
|
||||||
const bonds = styleObj.bonds;
|
const bonds = styleObj.bonds;
|
||||||
@@ -70,9 +71,6 @@ const apply3DmolStyle = function (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(styleObj).length > 0) {
|
if (Object.keys(styleObj).length > 0) {
|
||||||
if (!atoms.modelData) atoms.modelData = [];
|
|
||||||
const frameIdx = atoms.length - 1;
|
|
||||||
if (!atoms.modelData[frameIdx]) atoms.modelData[frameIdx] = {};
|
|
||||||
atoms.modelData[frameIdx].style = styleObj;
|
atoms.modelData[frameIdx].style = styleObj;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -140,6 +138,8 @@ const addBond = function (curFrame: any[], from: number, to: number, order: numb
|
|||||||
|
|
||||||
const parseV2000 = function (lines: any, options: ParserOptionsSpec) {
|
const parseV2000 = function (lines: any, options: ParserOptionsSpec) {
|
||||||
const atoms: any & Record<string, any> = [[]];
|
const atoms: any & Record<string, any> = [[]];
|
||||||
|
const modelData = atoms.modelData = [] as any[];
|
||||||
|
modelData.push({}); // entry for frame 0
|
||||||
const noH = typeof options.keepH !== "undefined" ? !options.keepH : false;
|
const noH = typeof options.keepH !== "undefined" ? !options.keepH : false;
|
||||||
let lineIndex = 0;
|
let lineIndex = 0;
|
||||||
|
|
||||||
@@ -192,7 +192,10 @@ const parseV2000 = function (lines: any, options: ParserOptionsSpec) {
|
|||||||
lineIndex = parseSDProperties(lines, lineIndex + offset, atoms, serialToIndex, start);
|
lineIndex = parseSDProperties(lines, lineIndex + offset, atoms, serialToIndex, start);
|
||||||
|
|
||||||
if (!options.multimodel) break;
|
if (!options.multimodel) break;
|
||||||
if (!options.onemol) atoms.push([]);
|
if (!options.onemol) {
|
||||||
|
atoms.push([]);
|
||||||
|
modelData.push({}); // 1:1 with frames — prevents undefined on frame switch
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return atoms;
|
return atoms;
|
||||||
};
|
};
|
||||||
@@ -205,6 +208,8 @@ const parseV2000 = function (lines: any, options: ParserOptionsSpec) {
|
|||||||
|
|
||||||
const parseV3000 = function (lines: any, options: ParserOptionsSpec) {
|
const parseV3000 = function (lines: any, options: ParserOptionsSpec) {
|
||||||
const atoms: any[][] & Record<string, any> = [[]];
|
const atoms: any[][] & Record<string, any> = [[]];
|
||||||
|
const modelData = atoms.modelData = [] as any[];
|
||||||
|
modelData.push({}); // entry for frame 0
|
||||||
const noH = typeof options.keepH !== "undefined" ? !options.keepH : false;
|
const noH = typeof options.keepH !== "undefined" ? !options.keepH : false;
|
||||||
let lineIndex = 0;
|
let lineIndex = 0;
|
||||||
|
|
||||||
@@ -280,7 +285,10 @@ const parseV3000 = function (lines: any, options: ParserOptionsSpec) {
|
|||||||
lineIndex = parseSDProperties(lines, lineIndex + offset, atoms, serialToIndex, start);
|
lineIndex = parseSDProperties(lines, lineIndex + offset, atoms, serialToIndex, start);
|
||||||
|
|
||||||
if (!options.multimodel) break;
|
if (!options.multimodel) break;
|
||||||
if (!options.onemol) atoms.push([]);
|
if (!options.onemol) {
|
||||||
|
atoms.push([]);
|
||||||
|
modelData.push({}); // 1:1 with frames
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return atoms;
|
return atoms;
|
||||||
|
|||||||
@@ -14,31 +14,41 @@ describe('Function SDF | parseV2000 |', ()=>{
|
|||||||
test("Atoms is empty when input data is not greater than 3 lines",()=>{
|
test("Atoms is empty when input data is not greater than 3 lines",()=>{
|
||||||
let test_data1 = "line1\nline2\nline3";
|
let test_data1 = "line1\nline2\nline3";
|
||||||
let test_atoms1 = $3Dmol.Parsers.SDF(test_data1, {});
|
let test_atoms1 = $3Dmol.Parsers.SDF(test_data1, {});
|
||||||
expect(test_atoms1).toEqual([[]]);
|
expect(test_atoms1.length).toBe(1);
|
||||||
|
expect(test_atoms1[0]).toEqual([]);
|
||||||
|
expect(test_atoms1.modelData).toEqual([{}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Atoms is empty when length of line 4 of input data is less than 38",()=>{
|
test("Atoms is empty when length of line 4 of input data is less than 38",()=>{
|
||||||
let test_data2 = "line1\nline2\nline3\nlessthan38";
|
let test_data2 = "line1\nline2\nline3\nlessthan38";
|
||||||
let test_atoms2 = $3Dmol.Parsers.SDF(test_data2, {});
|
let test_atoms2 = $3Dmol.Parsers.SDF(test_data2, {});
|
||||||
expect(test_atoms2).toEqual([[]]);
|
expect(test_atoms2.length).toBe(1);
|
||||||
|
expect(test_atoms2[0]).toEqual([]);
|
||||||
|
expect(test_atoms2.modelData).toEqual([{}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Atoms is empty when atomCount is not a number", ()=>{
|
test("Atoms is empty when atomCount is not a number", ()=>{
|
||||||
let test_data3 = "line1\nline2\nline3\natomCount";
|
let test_data3 = "line1\nline2\nline3\natomCount";
|
||||||
let test_atoms3 = $3Dmol.Parsers.SDF(test_data3, {});
|
let test_atoms3 = $3Dmol.Parsers.SDF(test_data3, {});
|
||||||
expect(test_atoms3).toEqual([[]]);
|
expect(test_atoms3.length).toBe(1);
|
||||||
|
expect(test_atoms3[0]).toEqual([]);
|
||||||
|
expect(test_atoms3.modelData).toEqual([{}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Atoms is empty when atomCount is not greater than 0", ()=>{
|
test("Atoms is empty when atomCount is not greater than 0", ()=>{
|
||||||
let test_data4 = "line1\nline2\nline3\n -1";
|
let test_data4 = "line1\nline2\nline3\n -1";
|
||||||
let test_atoms4 = $3Dmol.Parsers.SDF(test_data4, {});
|
let test_atoms4 = $3Dmol.Parsers.SDF(test_data4, {});
|
||||||
expect(test_atoms4).toEqual([[]]);
|
expect(test_atoms4.length).toBe(1);
|
||||||
|
expect(test_atoms4[0]).toEqual([]);
|
||||||
|
expect(test_atoms4.modelData).toEqual([{}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Atoms is empty when the number of lines of input is less than 4 + atomCount + bondCount", ()=>{
|
test("Atoms is empty when the number of lines of input is less than 4 + atomCount + bondCount", ()=>{
|
||||||
let test_data5 = "line1\nline2\nline3\n 1 0 ";// atomCount=0, bondCount=1
|
let test_data5 = "line1\nline2\nline3\n 1 0 ";// atomCount=0, bondCount=1
|
||||||
let test_atoms5 = $3Dmol.Parsers.SDF(test_data5, {});
|
let test_atoms5 = $3Dmol.Parsers.SDF(test_data5, {});
|
||||||
expect(test_atoms5).toEqual([[]]);
|
expect(test_atoms5.length).toBe(1);
|
||||||
|
expect(test_atoms5[0]).toEqual([]);
|
||||||
|
expect(test_atoms5.modelData).toEqual([{}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Length of atoms is 1", ()=>{
|
test("Length of atoms is 1", ()=>{
|
||||||
|
|||||||
Reference in New Issue
Block a user