Implements issue #4

This commit is contained in:
Rainer Simon 2020-04-30 20:34:24 +02:00
parent 9d85428e91
commit 41bd28185e
4 changed files with 54 additions and 14 deletions

View File

@ -36,7 +36,7 @@ export const CheckIcon = props => {
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 980 980" width={props.width}> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 980 980" width={props.width}>
<metadata>IcoFont Icons</metadata> <metadata>IcoFont Icons</metadata>
<title>verification-check</title> <title>verification-check</title>
<glyph glyph-name="verification-check" unicode="&#xf021;" horiz-adv-x="1000" /> <glyph glyphName="verification-check" unicode="&#xf021;" horizAdvX="1000" />
<path fill="currentColor" d="M792.9 162.8c-133.19999999999993 126.69999999999999-264.9 251.89999999999998-397.29999999999995 377.8-8.800000000000011 8.299999999999955-22.600000000000023 8-31-0.8000000000000682l-139.50000000000003-146.89999999999998c-8.299999999999983-8.799999999999955-22.5-9.399999999999977-31.599999999999994-1.5-41.19999999999999 36-82 71.70000000000005-123.7 108.20000000000005-9.099999999999994 8-9.899999999999999 21.699999999999932-1.7999999999999972 30.600000000000023 92.9 102.19999999999993 185 203.5 277.7 305.4 8.100000000000023 8.899999999999977 21.900000000000034 9.5 30.80000000000001 1.2999999999999545 185.29999999999995-172.39999999999998 369.29999999999995-343.7 553.8-515.3 8.900000000000091-8.200000000000045 9.600000000000023-22.30000000000001 1.7000000000000455-31.5-36.700000000000045-42.400000000000034-72.70000000000005-84.00000000000003-108.89999999999998-125.80000000000001-7.899999999999977-9.100000000000023-21.399999999999977-9.800000000000011-30.200000000000045-1.5z"/> <path fill="currentColor" d="M792.9 162.8c-133.19999999999993 126.69999999999999-264.9 251.89999999999998-397.29999999999995 377.8-8.800000000000011 8.299999999999955-22.600000000000023 8-31-0.8000000000000682l-139.50000000000003-146.89999999999998c-8.299999999999983-8.799999999999955-22.5-9.399999999999977-31.599999999999994-1.5-41.19999999999999 36-82 71.70000000000005-123.7 108.20000000000005-9.099999999999994 8-9.899999999999999 21.699999999999932-1.7999999999999972 30.600000000000023 92.9 102.19999999999993 185 203.5 277.7 305.4 8.100000000000023 8.899999999999977 21.900000000000034 9.5 30.80000000000001 1.2999999999999545 185.29999999999995-172.39999999999998 369.29999999999995-343.7 553.8-515.3 8.900000000000091-8.200000000000045 9.600000000000023-22.30000000000001 1.7000000000000455-31.5-36.700000000000045-42.400000000000034-72.70000000000005-84.00000000000003-108.89999999999998-125.80000000000001-7.899999999999977-9.100000000000023-21.399999999999977-9.800000000000011-30.200000000000045-1.5z"/>
</svg> </svg>
) )

View File

@ -82,8 +82,16 @@ export default class TextAnnotator extends Component {
this.selectionHandler.clearSelection(); this.selectionHandler.clearSelection();
this.highlighter.addOrUpdateAnnotation(annotation, previous); this.highlighter.addOrUpdateAnnotation(annotation, previous);
// A convenience method that allows the external application to
// override the autogenerated Id
const overrideId = originalId => forcedId =>
this.highlighter.overrideId(originalId, forcedId);
// Call CREATE or UPDATE handler // Call CREATE or UPDATE handler
this.props[method](annotation, previous); if (previous)
this.props[method](annotation.clone(), previous.clone());
else
this.props[method](annotation.clone(), overrideId(annotation.id));
} }
onDeleteAnnotation = annotation => { onDeleteAnnotation = annotation => {
@ -134,10 +142,15 @@ export default class TextAnnotator extends Component {
// otherwise, fire 'update' // otherwise, fire 'update'
const isNew = previous.annotation.bodies.length === 0; const isNew = previous.annotation.bodies.length === 0;
// A convenience method that allows the external application to
// override the autogenerated Id
const overrideId = originalId => forcedId =>
this.relationsLayer.overrideId(originalId, forcedId);
if (isNew) if (isNew)
this.props.onAnnotationCreated(relation.annotation); this.props.onAnnotationCreated(relation.annotation.clone(), overrideId(relation.annotation.id));
else else
this.props.onAnnotationUpdated(relation.annotation, previous.annotation); this.props.onAnnotationUpdated(relation.annotation.clone(), previous.annotation.clone());
} }
/** 'Delete' on the relation editor popup **/ /** 'Delete' on the relation editor popup **/
@ -152,7 +165,7 @@ export default class TextAnnotator extends Component {
/****************/ /****************/
addAnnotation = annotation => { addAnnotation = annotation => {
this.highlighter.addOrUpdateAnnotation(annotation); this.highlighter.addOrUpdateAnnotation(annotation.clone());
} }
removeAnnotation = annotation => { removeAnnotation = annotation => {
@ -165,14 +178,15 @@ export default class TextAnnotator extends Component {
} }
setAnnotations = annotations => { setAnnotations = annotations => {
this.highlighter.init(annotations).then(() => const clones = annotations.map(a => a.clone());
this.relationsLayer.init(annotations)); this.highlighter.init(clones).then(() =>
this.relationsLayer.init(clones));
} }
getAnnotations = () => { getAnnotations = () => {
const annotations = this.highlighter.getAllAnnotations(); const annotations = this.highlighter.getAllAnnotations();
const relations = this.relationsLayer.getAllRelations(); const relations = this.relationsLayer.getAllRelations();
return annotations.concat(relations); return annotations.concat(relations).map(a => a.clone());
} }
setMode = mode => { setMode = mode => {

View File

@ -53,17 +53,15 @@ export default class Highlighter {
} }
_findAnnotationSpans = annotation => { _findAnnotationSpans = annotation => {
// TODO index annotation to make this faster
const allAnnotationSpans = document.querySelectorAll('.r6o-annotation'); const allAnnotationSpans = document.querySelectorAll('.r6o-annotation');
return Array.prototype.slice.call(allAnnotationSpans) return Array.prototype.slice.call(allAnnotationSpans)
.filter(span => span.annotation.isEqual(annotation)); .filter(span => span.annotation.isEqual(annotation));
} }
getAllAnnotations = () => { getAllAnnotations = () => {
// TODO index annotation to make this faster
const allAnnotationSpans = document.querySelectorAll('.r6o-annotation'); const allAnnotationSpans = document.querySelectorAll('.r6o-annotation');
return Array.prototype.slice.call(allAnnotationSpans) const allAnnotations = Array.from(allAnnotationSpans).map(span => span.annotation);
.map(span => span.annotation); return [...new Set(allAnnotations)];
} }
addOrUpdateAnnotation = (annotation, maybePrevious) => { addOrUpdateAnnotation = (annotation, maybePrevious) => {
@ -90,6 +88,25 @@ export default class Highlighter {
} }
} }
/**
* Forces a new ID on the given annotation (or annotation with the given ID).
* This method handles the ID update within the Highlighter ONLY. It's up to
* the application to keep the RelationsLayer in sync!
*
* @returns the updated annotation for convenience
*/
overrideId = (annotationOrId, forcedId) => {
const id = annotationOrId.id ? annotationOrId.id : annotationOrId;
const allSpans = document.querySelectorAll(`.r6o-annotation[data-id="${id}"]`);
const annotation = allSpans[0].annotation;
const updatedAnnotation = annotation.clone({ id : forcedId });
this.bindAnnotation(updatedAnnotation, allSpans);
return updatedAnnotation;
}
_unwrapHighlightings(highlightSpans) { _unwrapHighlightings(highlightSpans) {
for (const span of highlightSpans) { for (const span of highlightSpans) {
const parent = span.parentNode; const parent = span.parentNode;
@ -106,7 +123,6 @@ export default class Highlighter {
bindAnnotation = (annotation, elements) => { bindAnnotation = (annotation, elements) => {
elements.forEach(el => { elements.forEach(el => {
el.annotation = annotation; el.annotation = annotation;
if (annotation.id)
el.dataset.id = annotation.id; el.dataset.id = annotation.id;
}); });
} }

View File

@ -93,6 +93,16 @@ export default class RelationsLayer extends EventEmitter {
} }
} }
overrideId = (annotationOrId, forcedId) => {
const id = annotationOrId.id ? annotationOrId.id : annotationOrId;
const conn = this.connections.find(c => c.annotation.id == id);
const updatedAnnotation = conn.annotation.clone({ id : forcedId });
conn.annotation = updatedAnnotation;
return conn;
}
getAllRelations = () => { getAllRelations = () => {
return this.connections.map(c => c.annotation); return this.connections.map(c => c.annotation);
} }