Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic editor #219

Merged
merged 69 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
bac7287
feat: add JS API to create a generic editor
targos Feb 9, 2024
4e5f760
chore: add Prettier scripts
targos Feb 10, 2024
054c457
Merge remote-tracking branch 'origin/main' into generic-editor
targos Jul 19, 2024
487fb01
chore: update ESLint config and lint all js code
targos Jul 19, 2024
b8857d5
chore: setup examples deployment with vite
targos Jul 19, 2024
e23ca05
chore: add get-java script
targos Jul 19, 2024
b697160
chore: fix jdk PATH syntax
targos Jul 19, 2024
2a5f763
chore: use Node.js 22 for build
targos Jul 19, 2024
d6a206b
wip: start working on CanvasEditor extension
targos Jul 19, 2024
7d44b49
feat: move poc code from examples to lib and install CanvasEditor in …
targos Jul 22, 2024
416a4ee
chore: remove unused imports
targos Jul 22, 2024
a470dce
chore: migrate poc page to ts
targos Jul 22, 2024
2fb5012
fix: grabFocus from java preventScroll now
tpoisseau Jul 23, 2024
cf77094
fix(Dialog): button ok on the right, cancel on the left
tpoisseau Jul 23, 2024
e0ed340
docs: add jsdoc to all CanvasEditor methods
targos Jul 23, 2024
7728439
chore: use correct hashbang in get-* scripts
targos Jul 23, 2024
579a66e
refactor: extract UI helper to separate class and use 16px cursor
targos Jul 23, 2024
57451bf
chore: add idea config for java modules
tpoisseau Jul 23, 2024
00a07e7
fix: repaint editor area after Dialog fireOk
tpoisseau Jul 23, 2024
e1c5007
fix: properly bind clickCount from dom mouse events to java fireMouse…
tpoisseau Jul 23, 2024
ec567e3
fix: use 24px size for cursors
targos Jul 23, 2024
9d60d9f
fix: implement drawRectangle
targos Jul 23, 2024
5951f11
feat: add readonly mode
tpoisseau Jul 23, 2024
9c0eb44
Merge remote-tracking branch 'origin/generic-editor' into generic-editor
tpoisseau Jul 23, 2024
581bba4
refactor: move readOnly to an options object
targos Jul 23, 2024
03ccf21
feat: add destroy method for cleanup
targos Jul 24, 2024
aecd411
feat: add support for touch screens
targos Jul 24, 2024
1f1da4e
refactor: restructure demo code
targos Jul 24, 2024
61f17d5
chore: add TailwindCSS for demo styles
targos Jul 24, 2024
c2a515c
feat: add option to set initial mode
targos Jul 24, 2024
acb6d45
docs: add reset button to demo page
targos Jul 24, 2024
df193bc
docs: retitle demo page
targos Jul 24, 2024
f63e816
feat: add clearAll method
targos Jul 24, 2024
e3e3bb9
fix: set highlight color to blue
tpoisseau Jul 24, 2024
34da498
Merge remote-tracking branch 'origin/generic-editor' into generic-editor
tpoisseau Jul 24, 2024
f178b1e
refactor: move seeds data
tpoisseau Jul 24, 2024
198f11f
fix: do not make first draw to soon
tpoisseau Jul 24, 2024
999f091
fix: draw toolbar before editor area
targos Jul 24, 2024
b939181
fix: select current tool before redraw
targos Jul 24, 2024
f6025c3
fix: jsDialog
targos Jul 24, 2024
9d5ebee
docs: update demo examples
targos Jul 24, 2024
c4ca78b
feat: prepare custom element
tpoisseau Jul 24, 2024
b6dfe35
Merge remote-tracking branch 'origin/generic-editor' into generic-editor
tpoisseau Jul 24, 2024
a915040
refactor: use animation frame to repaint editor area
targos Jul 25, 2024
f5422f0
refactor: init of canvas editor
targos Jul 25, 2024
8b8cb07
feat: add `getMode` method
targos Jul 25, 2024
2a79004
docs: empty all results on reset
targos Jul 25, 2024
467259a
docs: remove unused variable
targos Jul 25, 2024
f7eda57
chore: update exposed name
targos Jul 25, 2024
1e542ac
chore: continue implem of custom element
tpoisseau Jul 25, 2024
a3c6b70
Merge remote-tracking branch 'origin/generic-editor' into generic-editor
tpoisseau Jul 25, 2024
5a787be
fix: allow backspace for delete actions
targos Jul 25, 2024
55d9760
fix: add more checks for not destroyed
targos Jul 25, 2024
e67a254
fix: only create toolbar canvas if needed
targos Jul 25, 2024
ba0e4fb
docs: add readonly option to init and display molfile v2
targos Jul 25, 2024
dc6cb18
feat: add initialFragment option and trigger update on dialog submit
targos Jul 25, 2024
420361b
chore: update submodule
targos Jul 25, 2024
898d829
fix: rxn v3 bug
targos Jul 25, 2024
c2c9393
test: update snapshot
targos Jul 25, 2024
8e1d4b9
chore: continue implem of custom element
tpoisseau Jul 25, 2024
0b67d9c
chore: cast dom attributes values
tpoisseau Jul 25, 2024
d486cdc
fix: chromium derived do not support custom element extending builtin…
tpoisseau Jul 25, 2024
0bab565
fix: init and document styling
tpoisseau Jul 25, 2024
220bfde
fix: center dialog and isolate it with shadow dom
targos Jul 25, 2024
282d6a2
fix: remove shadow root from custom element
targos Jul 25, 2024
959e16d
refactor: do not init for nothing
targos Jul 25, 2024
d0de3da
fix: run mutatorHandler if this.#editor is defined
tpoisseau Jul 25, 2024
70bacec
chore: run Prettier
targos Jul 25, 2024
a4bcddb
docs: keep default height
targos Jul 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

9 changes: 0 additions & 9 deletions .eslintrc.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ jobs:
run: npm run build-debug-full
- name: Upload debug build and logs
if: failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: debug-build
name: debug-build-${{ matrix.node-version }}
path: |
dist/openchemlib-full.pretty.js
compile-full.log
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ war/**
*.log
/gwt/
gwt.zip
/jdk/
jdk.tar.gz
/dist/
/distbuild/
/distold/
/distesm/
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
9 changes: 9 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/CHANGELOG.md
/dist
/distbuild
/distesm
/distold
/gwt
/lib/canvas_editor/cursors_24px.js
/openchemlib
/war
17 changes: 17 additions & 0 deletions .run/Build java.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build java" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="npm run build-full-pretty" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
</configuration>
</component>
7 changes: 7 additions & 0 deletions .run/Run JS DEV.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run JS DEV" type="CompoundRunConfigurationType">
<toRun name="build-esm-bundle-watch" type="js.build_tools.npm" />
<toRun name="vite" type="js.build_tools.npm" />
<method v="2" />
</configuration>
</component>
12 changes: 12 additions & 0 deletions .run/build-esm-bundle-watch.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="build-esm-bundle-watch" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="build-esm-bundle-watch" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>
12 changes: 12 additions & 0 deletions .run/vite.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="vite" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="vite" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>
2 changes: 1 addition & 1 deletion __tests__/SmilesParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
const parser = new SmilesParser();
const coords1 = parser.parseMolecule(smiles).getIDCoordinates();
const coords2 = parser.parseMolecule(smiles).getIDCoordinates();
// TODO: Find a SMILES that goes through the random branch of coordinate invention.

Check warning on line 83 in __tests__/SmilesParser.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'todo' comment: 'TODO: Find a SMILES that goes through...'
// expect(coords1).not.toBe(coords2);
expect(coords1).toBe(coords2);
parser.setRandomSeed(1);
Expand Down Expand Up @@ -124,7 +124,7 @@

it('should should optionally not parse stereo features', () => {
const parser = new SmilesParser();
const vitaminA = 'C/C(=C\\CO)/C=C/C=C(/C)\\C=C\\C1=C(C)CCCC1(C)C';
const vitaminA = String.raw`C/C(=C\CO)/C=C/C=C(/C)\C=C\C1=C(C)CCCC1(C)C`;
const molecule = new Molecule(0, 0);
parser.parseMolecule(vitaminA, { molecule, noStereo: true });
const idCodeWithoutStereo = molecule.getIDCode();
Expand Down
8 changes: 8 additions & 0 deletions __tests__/__snapshots__/library.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

exports[`prototype properties of CanonizerUtil 1`] = `[]`;

exports[`prototype properties of CanvasEditor 1`] = `[]`;

exports[`prototype properties of ConformerGenerator 1`] = `
[
"getConformerCount",
Expand Down Expand Up @@ -405,6 +407,8 @@ exports[`prototype properties of Transformer 1`] = `

exports[`prototype properties of Util 1`] = `[]`;

exports[`prototype properties of registerCustomElement 1`] = `[]`;

exports[`static properties of CanonizerUtil 1`] = `
[
"BACKBONE",
Expand All @@ -416,6 +420,8 @@ exports[`static properties of CanonizerUtil 1`] = `
]
`;

exports[`static properties of CanvasEditor 1`] = `[]`;

exports[`static properties of ConformerGenerator 1`] = `
[
"STRATEGY_ADAPTIVE_RANDOM",
Expand Down Expand Up @@ -776,3 +782,5 @@ exports[`static properties of Util 1`] = `
"getHoseCodesFromDiastereotopicID",
]
`;

exports[`static properties of registerCustomElement 1`] = `[]`;
3 changes: 2 additions & 1 deletion __tests__/__snapshots__/reaction.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ exports[`Reaction class should load and create RXN files 2`] = `


OCL_RXN_V1.0:gJX@@eKU@@ gGQHDHaInfh@!gJX@@eKU@@ fHdP@@##!ROvp@[C}c@FNZz@@ !R_\`CW?Hc|_\`BH_Ykh@@ !ROvp@[C}c@FNZz@@ !RGP@@##
VM V30 BEGIN REACTANT
M V30 COUNTS 2 2
M V30 BEGIN REACTANT
M V30 BEGIN CTAB
M V30 COUNTS 6 5 0 0 0
M V30 BEGIN ATOM
Expand Down
20 changes: 13 additions & 7 deletions __tests__/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ const coreAPI = [
'Transformer',
];

const fullAPI = ['StructureView', 'StructureEditor', 'SVGRenderer'];
const fullAPI = [
'CanvasEditor',
'registerCustomElement',
'StructureView',
'StructureEditor',
'SVGRenderer',
];

const allAPI = [...minimalAPI, ...coreAPI, ...fullAPI];

Expand All @@ -47,12 +53,12 @@ test('core', () => {
});

test('full', () => {
[full, pretty].forEach((lib) => {
for (const lib of [full, pretty]) {
checkHas(lib, allAPI);
});
}
});

allAPI.forEach((key) => {
for (const key of allAPI) {
const api = full[key];
if (typeof api === 'function') {
test(`static properties of ${key}`, () => {
Expand All @@ -64,16 +70,16 @@ allAPI.forEach((key) => {
});
}
}
});
}

function checkHas(obj, properties) {
expect(Object.keys(obj).sort()).toStrictEqual(properties.sort());
}

function checkHasNot(obj, properties) {
properties.forEach((prop) => {
for (const prop of properties) {
expect(obj).not.toHaveProperty(prop);
});
}
}

function getFilteredKeys(obj) {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/molecule.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const fs = require('fs');
const fs = require('node:fs');

const { Molecule } = require('../minimal');

Expand Down
10 changes: 6 additions & 4 deletions __tests__/molfileAndAtomMapNo.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const { readFileSync } = require('fs');
const { readFileSync } = require('node:fs');

const { Molecule } = require('../minimal');

Expand All @@ -11,9 +11,11 @@ test('molfile with atomMapNo', () => {
const newMolfile = molecule.toMolfile();
const atomMapNo = newMolfile
.split(/\r?\n/)
.filter((line) => line.match(/ [OCH] /))
// eslint-disable-next-line prefer-named-capture-group
.map((line) => line.replace(/.* ([OCH]) .*(.) {2}0 {2}0$/, '$1 $2'));
.filter((line) => line.match(/ [CHO] /))
.map((line) =>
line.replace(/.* (?<och>[CHO]) .*(?<n>.) {2}0 {2}0$/, '$<och> $<n>'),
);

expect(atomMapNo).toStrictEqual(['O 5', 'C 1', 'C 3', 'C 4', 'H 2']);

const svg = molecule.toSVG(300, 200);
Expand Down
3 changes: 1 addition & 2 deletions __tests__/sssearcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ describe('SSSearcher', () => {
let benzeneFragment = Molecule.fromSmiles('c1ccccc1');
benzeneFragment.setFragment(true);
let ethylBenzene = Molecule.fromSmiles('CCc1ccccc1');
let allicin = Molecule.fromSmiles('O=S(SC\\C=C)C\\C=C');

let allicin = Molecule.fromSmiles(String.raw`O=S(SC\C=C)C\C=C`);
it('should find in itself', () => {
let searcher = new SSSearcher();
searcher.setMolecule(benzene);
Expand Down
2 changes: 1 addition & 1 deletion __tests__/sssearcher_with_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ function getTestData() {
const ethylBenzene = Molecule.fromSmiles('CCc1ccccc1');
const ethylBenzeneIndex = searcher.createIndex(ethylBenzene);

const allicin = Molecule.fromSmiles('O=S(SC\\C=C)C\\C=C');
const allicin = Molecule.fromSmiles(String.raw`O=S(SC\C=C)C\C=C`);
const allicinIndex = searcher.createIndex(allicin);
return {
benzene,
Expand Down
3 changes: 0 additions & 3 deletions benchmark/.eslintrc.yml

This file was deleted.

24 changes: 0 additions & 24 deletions benchmark/diastereoID.js

This file was deleted.

16 changes: 16 additions & 0 deletions benchmark/diastereoID.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { getDiastereotopicAtomIDs } from 'openchemlib-utils';

import { Molecule, version } from '../full.js';

console.log('OCL version', version);
console.time('diastereoID');
const response = await fetch('https://wikipedia.cheminfo.org/data.json');
const { data } = await response.json();
let totalLength = 0;
for (const entry of data.molecules.slice(0, 700)) {
const molecule = Molecule.fromIDCode(entry.idCode);
const ids = getDiastereotopicAtomIDs(molecule);
totalLength += ids.length;
}
console.timeEnd('diastereoID');
console.log(totalLength);
8 changes: 3 additions & 5 deletions benchmark/molfile.js → benchmark/molfile.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';
import Benchmark from 'benchmark';

const Benchmark = require('benchmark');

const OCLOld = require('../distold/openchemlib-full.pretty');
const OCLNew = require('../full.pretty');
import OCLOld from '../distold/openchemlib-full.pretty.js';
import OCLNew from '../full.pretty.js';

const idcode = 'enYXNH@MHDAELem`OCIILdhhdiheCDlieKDdefndZRVVjjfjjfjihJBbb@@@';
const mol = OCLNew.Molecule.fromIDCode(idcode);
Expand Down
8 changes: 3 additions & 5 deletions benchmark/sssearcher.js → benchmark/sssearcher.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';
import Benchmark from 'benchmark';

const Benchmark = require('benchmark');

const OCLOld = require('../distold/openchemlib-full.pretty');
const OCLNew = require('../full.pretty');
import OCLOld from '../distold/openchemlib-full.pretty.js';
import OCLNew from '../full.pretty.js';

let benzeneFragmentNew = OCLNew.Molecule.fromSmiles('c1ccccc1');
benzeneFragmentNew.setFragment(true);
Expand Down
22 changes: 0 additions & 22 deletions benchmark/wikipedia.js

This file was deleted.

14 changes: 14 additions & 0 deletions benchmark/wikipedia.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Molecule, version } from '../full.js';

console.log('OCL version', version);
console.time('wikipedia');
const response = await fetch('https://wikipedia.cheminfo.org/data.json');
const { data } = await response.json();
const idCodes = [];
for (const entry of data.molecules.slice(0, 10000)) {
const molecule = Molecule.fromIDCode(entry.idCode);
const idCode = molecule.getIDCode();
idCodes.push(idCode);
}
console.timeEnd('wikipedia');
console.log(idCodes.join(',').length);
Loading