diff --git a/src/App.jsx b/src/App.jsx deleted file mode 100644 index eed29ff..0000000 --- a/src/App.jsx +++ /dev/null @@ -1,218 +0,0 @@ -import React, { Component } from 'react'; -import { - Editor, - Highlighter, - SelectionHandler, - RelationsLayer, - RelationEditor - } from 'recogito-client-core'; - -import 'recogito-client-core/themes/default'; - -/** - * Pulls the strings between the annotation highlight layer - * and the editor popup. - */ -export default class App extends Component { - - state = { - showEditor: false, - selectionBounds: null, - selectedAnnotation: null, - - showRelationEditor: false, - selectedRelation: null - } - - /** Helper **/ - _clearState = () => { - this.setState({ - showEditor: false, - selectionBounds: null, - selectedAnnotation: null - }); - } - - handleEscape = (evt) => { - if (evt.which === 27) - this.onCancelAnnotation(); - } - - componentDidMount() { - this.highlighter = new Highlighter(this.props.contentEl, this.props.formatter); - - this.selectionHandler = new SelectionHandler(this.props.contentEl, this.highlighter); - this.selectionHandler.on('select', this.handleSelect); - - this.relationsLayer = new RelationsLayer(this.props.contentEl); - this.relationsLayer.readOnly = true; // Deactivate by default - - this.relationsLayer.on('createRelation', this.onEditRelation); - this.relationsLayer.on('selectRelation', this.onEditRelation); - this.relationsLayer.on('cancelDrawing', this.closeRelationsEditor); - - document.addEventListener('keydown', this.handleEscape); - } - - componentWillUnmount() { - document.removeEventListener('keydown', this.handleEscape); - } - - /**************************/ - /* Annotation CRUD events */ - /**************************/ - - /** Selection on the text **/ - handleSelect = evt => { - const { selection, clientRect } = evt; - if (selection) { - this.setState({ - showEditor: true, - selectionBounds: clientRect, - selectedAnnotation: selection - }); - } else { - this._clearState(); - } - } - - /** Common handler for annotation CREATE or UPDATE **/ - onCreateOrUpdateAnnotation = method => (annotation, previous) => { - // Clear the annotation layer - this._clearState(); - - this.selectionHandler.clearSelection(); - this.highlighter.addOrUpdateAnnotation(annotation, previous); - - // Call CREATE or UPDATE handler - this.props[method](annotation, previous); - } - - onDeleteAnnotation = annotation => { - // Delete connections - const connections = this.relationsLayer.getConnectionsFor(annotation); - connections.forEach(c => c.destroy()); - - this._clearState(); - this.selectionHandler.clearSelection(); - this.highlighter.removeAnnotation(annotation); - } - - /** Cancel button on annotation editor **/ - onCancelAnnotation = () => { - this._clearState(); - this.selectionHandler.clearSelection(); - } - - /************************/ - /* Relation CRUD events */ - /************************/ - - // Shorthand - closeRelationsEditor = () => { - this.setState({ showRelationEditor: false }); - this.relationsLayer.resetDrawing(); - } - - /** - * Selection on the relations layer: open an existing - * or newly created connection for editing. - */ - onEditRelation = relation => { - this.setState({ - showRelationEditor: true, - selectedRelation: relation - }); - } - - /** 'Ok' on the relation editor popup **/ - onCreateOrUpdateRelation = (relation, previous) => { - this.relationsLayer.addOrUpdateRelation(relation, previous); - this.closeRelationsEditor(); - } - - /** 'Delete' on the relation editor popup **/ - onDeleteRelation = relation => { - this.relationsLayer.removeRelation(relation); - this.closeRelationsEditor(); - } - - /****************/ - /* External API */ - /****************/ - - addAnnotation = annotation => { - this.highlighter.addOrUpdateAnnotation(annotation); - } - - removeAnnotation = annotation => { - this.highlighter.removeAnnotation(annotation); - - // If the editor is currently open on this annotation, close it - const { selectedAnnotation } = this.state; - if (selectedAnnotation && annotation.isEqual(selectedAnnotation)) - this.setState({ showEditor: false }); - } - - setAnnotations = annotations => { - this.highlighter.init(annotations); - this.relationsLayer.init(annotations); - } - - getAnnotations = () => { - const annotations = this.highlighter.getAllAnnotations(); - const relations = this.relationsLayer.getAllRelations(); - return annotations.concat(relations); - } - - setMode = mode => { - if (mode === 'RELATIONS') { - this.setState({ showEditor: false }); - - this.selectionHandler.enabled = false; - - this.relationsLayer.readOnly = false; - this.relationsLayer.startDrawing(); - } else { - this.setState({ showRelationEditor: false }); - - this.selectionHandler.enabled = true; - - this.relationsLayer.readOnly = true; - this.relationsLayer.stopDrawing(); - } - } - - render() { - return ( - <> - { this.state.showEditor && - - - {this.props.children} - - - } - - { this.state.showRelationEditor && - - } - - ); - } - -} \ No newline at end of file diff --git a/src/index.js b/src/index.js index f233e2c..c2d51d3 100644 --- a/src/index.js +++ b/src/index.js @@ -2,8 +2,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; import axios from 'axios'; import Emitter from 'tiny-emitter'; -import { Editor, WebAnnotation, deflateHTML } from 'recogito-client-core'; -import App from './App'; +import { TextAnnotator, Editor, WebAnnotation, deflateHTML } from 'recogito-client-core'; + +import 'recogito-client-core/themes/default'; /** * The entrypoint into the application. Provides the @@ -27,9 +28,8 @@ class Recogito { // Unless this is preformatted text, remove multi spaces and // empty text node, so that HTML char offsets == browser offsets. - if (config.mode !== 'pre') { + if (config.mode !== 'pre') content = deflateHTML(content); - } const wrapper = document.createElement('DIV'); wrapper.style.position = 'relative'; @@ -39,8 +39,11 @@ class Recogito { const container = document.createElement('DIV'); wrapper.appendChild(container); + const { CommentWidget, TagWidget } = Editor; + + // A basic TextAnnotator with just a comment and a tag widget ReactDOM.render( - - {/* A basic editor with just a comment & tagwidget */} - - + + - , + , container); } - handleAnnotationCreated = annotation => { + handleAnnotationCreated = annotation => this._emitter.emit('createAnnotation', annotation); - } - handleAnnotationUpdated = (annotation, previous) => { + handleAnnotationUpdated = (annotation, previous) => this._emitter.emit('updateAnnotation', annotation, previous); - } - handleAnnotationDeleted = annotation => { + handleAnnotationDeleted = annotation => this._emitter.emit('deleteAnnotation', annotation); - } /******************/ /* External API */ @@ -78,16 +77,14 @@ class Recogito { /** * Adds a JSON-LD WebAnnotation to the annotation layer. */ - addAnnotation = annotation => { + addAnnotation = annotation => this._app.current.addAnnotation(new WebAnnotation(annotation)); - } /** * Removes the given JSON-LD WebAnnotation from the annotation layer. */ - removeAnnotation = annotation => { + removeAnnotation = annotation => this._app.current.removeAnnotation(new WebAnnotation(annotation)); - } /** * Loads JSON-LD WebAnnotations from the given URL. @@ -108,16 +105,14 @@ class Recogito { * Activates annotation or relationship drawing mode. * @param mode a string, either ANNOTATION (default) or RELATIONS */ - setMode = mode => { + setMode = mode => this._app.current.setMode(mode); - } /** * Adds an event handler. */ - on = (event, handler) => { + on = (event, handler) => this._emitter.on(event, handler); - } /** * Removes an event handler. @@ -125,13 +120,10 @@ class Recogito { * If no callback, removes all handlers for * the given event. */ - off = (event, callback) => { + off = (event, callback) => this._emitter.off(event, callback); - } } -export const init = config => { - return new Recogito(config); -} +export const init = config => new Recogito(config);