Skip to content

Commit

Permalink
feat: add clipboard listener
Browse files Browse the repository at this point in the history
  • Loading branch information
tpoisseau committed Oct 11, 2024
1 parent 2575d9e commit cd44ff7
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .run/Build java.run.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build java" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="npm run build-full-pretty" />
<option name="SCRIPT_TEXT" value="npm run build-full-pretty -- --verbose" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="" />
<option name="SCRIPT_OPTIONS" value="" />
Expand Down
13 changes: 9 additions & 4 deletions lib/canvas_editor/clipboard_handler.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
'use strict';

class ClipboardHandler {
/**
* @param {Molecule} molecule
* @return {boolean}
*/
copyMolecule(molecule) {
const data = molecule.getIDCodeAndCoordinates();
navigator.clipboard.writeText(`${data.idCode} ${data.coordinates}`);
void navigator.clipboard.writeText(`${data.idCode} ${data.coordinates}`);
return true;
}

pasteMolecule() {
// TODO: find a way to implement this in a synchronous way.
return null;
putString(data) {
void navigator.clipboard.writeText(data);
return true;
}
}

Expand Down
72 changes: 12 additions & 60 deletions lib/canvas_editor/create_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

const EditorArea = require('./editor_area');
const getEditorStylesheet = require('./editor_stylesheet');
const { addPointerListeners, addKeyboardListeners } = require('./events');
const {
addPointerListeners,
addKeyboardListeners,
addClipboardListeners,
} = require('./events');
const Toolbar = require('./toolbar');
const UIHelper = require('./ui_helper');

Expand All @@ -15,7 +19,6 @@ function createEditor(
JavaUIHelper,
Molecule,
Reaction,
ReactionEncoder,
) {
const {
readOnly = false,
Expand Down Expand Up @@ -74,15 +77,6 @@ function createEditor(
uiHelper,
);

/**
* @return {'reaction' | 'molecule'}
*/
function getMode() {
const mode = editorArea.getMode();
const isReaction = mode & (JavaEditorArea.MODE_REACTION !== 0);
return isReaction ? 'reaction' : 'molecule';
}

if (initialFragment) {
if (initialMode === 'molecule') {
const fragmentMolecule = new Molecule(0, 0);
Expand Down Expand Up @@ -136,62 +130,20 @@ function createEditor(
);
}

/**
* @param {ClipboardEvent} event
*/
function onPaste(event) {
const idcode = event.clipboardData.getData('text/plain');
if (!idcode) return;

switch (getMode()) {
case 'molecule': {
const molecule = Molecule.fromIDCode(idcode);
editorArea.setMolecule(molecule);
break;
}
case 'reaction': {
const reaction = ReactionEncoder.decode(idcode);
editorArea.setReaction(reaction);
break;
}
default: {
throw new Error(`Mode ${getMode()} is not supported`);
}
}
}

function onCopy(event) {
switch (getMode()) {
case 'molecule': {
const idcode = editorArea.getMolecule().getIDCode();
event.clipboardData.setData('text/plain', idcode);
break;
}
case 'reaction': {
const idcode = ReactionEncoder.encode(editorArea.getReaction());
event.clipboardData.setData('text/plain', idcode);
break;
}
default: {
throw new Error(`Mode ${getMode()} is not supported`);
}
}
}

if (!readOnly) {
rootElement.addEventListener('paste', onPaste);
}
rootElement.addEventListener('copy', onCopy);
const removeClipboardListeners = addClipboardListeners(
rootElement,
editorArea,
readOnly,
JavaEditorArea,
);

function destroy() {
rootElement.remove();
resizeObserver.disconnect();
removePointerListeners?.();
removeKeyboardListeners?.();
removeToolbarPointerListeners?.();

rootElement.removeEventListener('paste', onPaste);
rootElement.removeEventListener('copy', onCopy);
removeClipboardListeners?.();
}

return { editorArea, toolbar, uiHelper, destroy };
Expand Down
55 changes: 54 additions & 1 deletion lib/canvas_editor/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function addPointerListeners(canvasElement, drawArea, JavaEditorArea) {
function addKeyboardListeners(canvasElement, editorArea, JavaEditorArea) {
const isMac =
typeof navigator !== 'undefined' && navigator.platform === 'MacIntel';
const isMenuKey = (ev) => (isMac && ev.metaKey) || (!isMac && ev.ctrlKey);

function fireKeyEvent(what, ev) {
const key = getKeyFromEvent(ev, JavaEditorArea);
Expand All @@ -82,11 +83,15 @@ function addKeyboardListeners(canvasElement, editorArea, JavaEditorArea) {
ev.altKey,
ev.ctrlKey,
ev.shiftKey,
(isMac && ev.metaKey) || (!isMac && ev.ctrlKey),
isMenuKey(ev),
);
}

canvasElement.addEventListener('keydown', (ev) => {
// copy-paste is handled by the clipboard event
if (isMenuKey(ev) && ev.key === 'c') return;
if (isMenuKey(ev) && ev.key === 'v') return;

fireKeyEvent(JavaEditorArea.KEY_EVENT_PRESSED, ev);
});
canvasElement.addEventListener('keyup', (ev) => {
Expand Down Expand Up @@ -129,7 +134,55 @@ function getKeyFromEvent(ev, JavaEditorArea) {
}
}

/**
*
* @param {HTMLDivElement} rootElement
* @param editorArea
* @param {boolean} readOnly
* @param JavaEditorArea
*/
function addClipboardListeners(
rootElement,
editorArea,
readOnly,
JavaEditorArea,
) {
/**
* @param {ClipboardEvent} event
*/
function onCopy(event) {
editorArea.fireClipboardEvent(JavaEditorArea.CLIPBOARD_EVENT_COPY, null);

event.preventDefault();
event.stopPropagation();
}

/**
* @param {ClipboardEvent} event
*/
function onPaste(event) {
const idcode = event.clipboardData.getData('text/plain');
if (!idcode) return;

editorArea.fireClipboardEvent(JavaEditorArea.CLIPBOARD_EVENT_PASTE, idcode);

event.preventDefault();
event.stopPropagation();
}

rootElement.addEventListener('copy', onCopy);
if (!readOnly) {
rootElement.addEventListener('paste', onPaste);
}

return () => {
rootElement.removeEventListener('copy', onCopy);
rootElement.removeEventListener('paste', onPaste);
};
}

module.exports = {
addPointerListeners,
addKeyboardListeners,
addClipboardListeners,
};
2 changes: 0 additions & 2 deletions lib/canvas_editor/init/canvas_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ function initCanvasEditor(
JavaUIHelper,
Molecule,
Reaction,
ReactionEncoder,
) {
class CanvasEditor {
#isReadOnly;
Expand All @@ -33,7 +32,6 @@ function initCanvasEditor(
JavaUIHelper,
Molecule,
Reaction,
ReactionEncoder,
);
this.#isReadOnly = readOnly;
this.#editorArea = editorArea;
Expand Down
1 change: 0 additions & 1 deletion lib/canvas_editor/init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ function init(OCL) {
JavaUIHelper,
Molecule,
Reaction,
ReactionEncoder,
);

function registerCustomElement() {
Expand Down
Loading

0 comments on commit cd44ff7

Please sign in to comment.